Python string substitution picking up junk characters in api requests - python-3.x

I am using Pagerduty python api client - pdpyras And below is the block of code
session = APISession(api_token)
changedate = os.popen("date -u -d '24 hours ago' +'%FT%T%.2Z'").read()
print(changedate)
changeurl = "change_events?include[]=integration&since=" + changedate
print(changeurl)
change_dump = session.rget(changeurl)
print(change_dump[0])
This should ideally get me the 1st event from change-events page of pagerduty. However, it fails due to the junk characters that gets added in the changeurl when it is passed to session.rget
See the below output
2021-03-26T09:47:53.2Z
change_events?include[]=integration&since=2021-03-26T09:47:53.2Z
Traceback (most recent call last):
File "dailyincidents.py", line 28, in <module>
change_dump = session.rget(changeurl)
File "/Users/saha/.pyenv/versions/3.7.7/lib/python3.7/site-packages/pdpyras.py", line 190, in call
return method(self, url, **kw)
File "/Users/saha/.pyenv/versions/3.7.7/lib/python3.7/site-packages/pdpyras.py", line 143, in call
r = raise_on_error(method(self, path, **pass_kw))
File "/Users/saha/.pyenv/versions/3.7.7/lib/python3.7/site-packages/pdpyras.py", line 84, in raise_on_error
), response=r
pdpyras.PDClientError: GET /change_events?include%5B%5D=integration&since=2021-03-26T09:47:53.2Z%0A: API responded with non-success status (400)
The problem here is the junk characters you see in the last line of error "include%5B%5D" and then "%0A" in the end. Because if I run the below code block directly, I am able to successfully pull the details.
change_dump = session.rget("change_events?include[]=integration&since=2021-03-26T09:47:53.2Z")
The issue occurs only when the string gets substituted, it takes these junk characters. Not sure how it gets picked and how to get around this. Any pointers?
EDIT
I was able to partly get rid of the junk characters. However, there is still one at the end, which I am not sure how to. Below is the change I did.
parameters = "include[]=integration&since=" + changedate
change_dump = session.rget("change_events", params=parameters)
Now, the error is like below
pdpyras.PDClientError: GET
/change_events?include[]=integration&since=2021-03-26T14:14:08.2Z%0A:
API responded with non-success status (400)
As you can see, now the last 3 characters in the url which is %0A: is causing the problem. Any pointers please?

The below format should work for you.
parameters = "include[]=integration&since=" + changedate
change_dump = session.rget("change_events",params=parameters.rstrip('\n').replace("\n", ""))

Related

AWS secret manager time out sometimes

I am fetching a secret from secret manager on a lambda. The request fails sometimes. Which is totally strange, it is working fine and couple of hours later I check and I am getting time out.
def get_credentials(self):
"""Retrieve credentials from the Secrets Manager service."""
boto_config = BotoConfig(connect_timeout=3, retries={"max_attempts": 3})
secrets_client = self.boto_session.client(
service_name="secretsmanager",
region_name=self.boto_session.region_name,
config=boto_config,
)
secret_value = secrets_client.get_secret_value(SecretId=self._secret_name)
secret = secret_value["SecretString"]
I try to debug the lambda and later seems to be working again, without any change, those state changes happen in hours. Any hint why that could happen?
Traceback (most recent call last):
File "/opt/python/botocore/endpoint.py", line 249, in _do_get_response
http_response = self._send(request)
File "/opt/python/botocore/endpoint.py", line 321, in _send
return self.http_session.send(request)
File "/opt/python/botocore/httpsession.py", line 438, in send
raise ConnectTimeoutError(endpoint_url=request.url, error=e)
botocore.exceptions.ConnectTimeoutError: Connect timeout on endpoint URL: "https://secretsmanager.eu-central-1.amazonaws.com/"
You are using the legacy retry mode (is the default one in boto3), which has very limited functionality as it only works for a very limited number of errors.
You should try changing your retry strategy to something like Standard retry mode or Adaptative. In that case your code would look like:
from botocore.config import Config as BotoConfig
boto_config = BotoConfig(
connect_timeout=3,
retries={
"max_attempts": 3,
"mode":"standard"
}
)
secrets_client = self.boto_session.client(
service_name="secretsmanager",
region_name=self.boto_session.region_name,
config=boto_config,
)

Websocket error: "Handhshake status 403 forbidden"

i have a problem with my written code which i wrote with the help of this documentation: https://exchange.blockchain.com/api/#introduction.
The code should send messages, receive messages and then i want to work with the received messages. And that 3 times per day (in the morning, noon and evening).
However the code seems to be working sometimes, actually up to 6 days (record, yay!) and then it stops working and i get an error output:
Traceback (most recent call last):
File "<ipython-input-1-052db9d33d34>", line 1, in <module>
runfile('Pathtofile/File.py', wdir='workingdirectory')
File "C:\Users\iamdabest\Downloads\latexNpython\WinPython64-3.6.8.0\python-
3.6.8.amd64\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line
786, in runfile
execfile(filename, namespace)
File "C:\Users\orami?\Downloads\latexNpython\WinPython64-3.6.8.0\python-
3.6.8.amd64\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line
110, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "Pathtofile/File.py", line 235, in <module>
main()
File "Pathtofile/File.py", line 229, in main
trigger(updater.bot)
File "Pathtofile/File.py", line 171, in trigger
y = price_func()[0]
File "Pathtofile/File.py", line 46, in price_func
ws = create_connection(url, **options)
File "C:\Users\name\Downloads\latexNpython\WinPython64-3.6.8.0\python-
3.6.8.amd64\lib\site-packages\websocket\_core.py", line 606, in
create_connection
websock.connect(url, **options)
File "C:\Users\name\Downloads\latexNpython\WinPython64-3.6.8.0\python-
3.6.8.amd64\lib\site-packages\websocket\_core.py", line 253, in connect
self.handshake_response = handshake(self.sock, *addrs, **options)
File "C:\Users\name\Downloads\latexNpython\WinPython64-3.6.8.0\python-
3.6.8.amd64\lib\site-packages\websocket\_handshake.py", line 57, in handshake
status, resp = _get_resp_headers(sock)
File "C:\Users\name\Downloads\latexNpython\WinPython64-3.6.8.0\python-
3.6.8.amd64\lib\site-packages\websocket\_handshake.py", line 143, in
_get_resp_headers
raise WebSocketBadStatusException("Handshake status %d %s", status,
status_message, resp_headers)
WebSocketBadStatusException: Handshake status 403 Forbidden
Now please keep in mind that i never got teached this stuff by a trained professional. All the knowledge i gained is from playing around (plotting and analyzing data) with python and the help of the internet.
I don't really understand why it is working few days and then suddenly stops working.
My questions:
In fact i have no problem when the codes doesn't gives an output as long as it keeps running. So how can i tell the code to 'ignore' the error and keep moving or maybe to automatic restart the code if the error occurs? I tried simple stuff like if statement or try and expect but i wasn't successful.
The error comes because the authentication between Server and Client failed? or what does it mean?
Is there another workaround? I already read somewhere to use another websocket (websockets) but wasn't able to get it working.
Here is a (M)WE of my code:
from websocket import create_connection
import json
options = {}
options['origin'] = 'https://exchange.blockchain.com'
url = "wss://ws.prod.blockchain.info/mercury-gateway/v1/ws"
def price_func():
ws = create_connection(url, **options)
msg = '{"token": "mysecretAPItoken", "action": "subscribe", "channel": "auth"}' # here i subscribe
ws.send(msg)
msg = '{"action": "subscribe", "channel": "balances"}' # here i am asking for the json files
ws.send(msg)
result1 = json.loads(ws.recv()) # first answer is the confirmation of connecting
result2 = json.loads(ws.recv()) # save the received answers to work with them later
msg = '{"token": "mysecretAPItoken", "action": "unsubscribe", "channel": "balances"}' # unsubscribing, not sure if i need to do that but it seems to me like 'clean' working; if smth goes wrong it unsubscribes.
ws.send(msg)
msg = '{"token": "mysecretAPItoken", "action": "unsubscribe", "channel": "auth"}' # unsubscribing; same as 3 lines above
ws.send(msg)
ws.close()
return result2['balances'][0]['rate'], result2['balances'][1]['rate'] # gives me the prices
x = price_func()[0]
print('Price of Shitcoin is around' + str(round(x,2)))
Thx for any help.

Trouble sending a batch create entity request in dialogflow

I have defined the following function. The purpose is to make batch create entity request with dialogflow client. I am using this method after sending many individual tests did not scale well.
The problem seems to be the line that defines EntityType. Seems like "entityType" is not valid but that is what is in the dialogflow v2 documentation which is the current version I am using.
Any ideas on what the issue is?
def create_batch_entity_types(self):
client = self.get_entity_client()
print(DialogFlowClient.batch_list)
EntityType = {
"entityTypes": DialogFlowClient.batch_list
}
response = client.batch_update_entity_types(parent=AGENT_PATH, entity_type_batch_inline=EntityType)
def callback(operation_future):
# Handle result.
result = operation_future.result()
print(result)
response.add_done_callback(callback)
After running the function I received this error
Traceback (most recent call last):
File "df_client.py", line 540, in <module>
create_entity_types_from_database()
File "df_client.py", line 426, in create_entity_types_from_database
df.create_batch_entity_types()
File "/Users/andrewflorial/Documents/PROJECTS/curlbot/dialogflow/dialogflow_accessor.py", line 99, in create_batch_entity_types
response = client.batch_update_entity_types(parent=AGENT_PATH, entity_type_batch_inline=EntityType)
File "/Users/andrewflorial/Documents/PROJECTS/curlbot/venv/lib/python3.7/site-packages/dialogflow_v2/gapic/entity_types_client.py", line 767, in batch_update_entity_types
update_mask=update_mask,
ValueError: Protocol message EntityTypeBatch has no "entityTypes" field.
The argument for entity_type_batch_inline must have the same form as EntityTypeBatch.
Look how that type looks like: https://dialogflow-python-client-v2.readthedocs.io/en/latest/gapic/v2/types.html#dialogflow_v2.types.EntityTypeBatch
It has to have entity_types field, not entityTypes.

Jira Python API to insert comment with WIKI formatting

While using jira python module to add comments, is there a possibility to insert comments using WIKI markup?
I noticed some example showed REST API calls with representation:wiki can do this.
But I noticed current python Jira only supports plain text as comments. Is this a limitation or I am missing something?
I checked jira source code and noticed data is represented as dictionary and also being dumped using json.dumps, I tried pushing body as dict "{'storage': {'value': '== Activity: == error-rate-percentage-is-at-acceptable-limits .. Started', 'representation': 'wiki'}}"
But got below error back from Jira API call I guess
[2019-12-02 01:07:22 DEBUG] [__init__:386] Before-control 'jira-integration' failed
Traceback (most recent call last):
File "<<HIDDEN BY ME>>>/lib/python3.7/site-packages/chaoslib/control/__init__.py", line 377, in apply_controls
settings=settings)
File "<<HIDDEN BY ME>>>/python3.7/site-packages/chaoslib/control/python.py", line 147, in apply_python_control
func(context=context, **arguments)
File "<<HIDDEN BY ME>>>/python3.7/site-packages/<<HIDDEN BY ME>>/controls/jira/tickets.py", line 220, in before_activity_control
add_comment(os.environ["SUB_TASK_TICKET"], content_as_wiki(formatting.format_as_heading2("Activity: ") + str(context["name"]) + " .. Started"))
File "<<HIDDEN BY ME>>>/python3.7/site-packages/<<HIDDEN BY ME>>/controls/jira/tickets.py", line 58, in add_comment
test = JIRA_CLIENT.add_comment(issue, comment)
File "<<HIDDEN BY ME>>/python3.7/site-packages/jira/client.py", line 126, in wrapper
result = func(*arg_list, **kwargs)
File "<<HIDDEN BY ME>>/python3.7/site-packages/jira/client.py", line 1367, in add_comment
url, data=json.dumps(data)
File "<<HIDDEN BY ME>>/python3.7/site-packages/jira/resilientsession.py", line 154, in post
return self.__verb('POST', url, **kwargs)
File "<<HIDDEN BY ME>>/python3.7/site-packages/jira/resilientsession.py", line 147, in __verb
raise_on_error(response, verb=verb, **kwargs)
File "<<HIDDEN BY ME>>/python3.7/site-packages/jira/resilientsession.py", line 57, in raise_on_error
r.status_code, error, r.url, request=request, response=r, **kwargs)
jira.exceptions.JIRAError: JiraError HTTP 400 url: https://<<HIDDEN BY ME>>>
text: Can not deserialize instance of java.lang.String out of START_OBJECT token
at [Source: com.enhancera.auditor.common.filter.RestReadingServletRequest$1#4e08280a; line: 1, column: 2] (through reference chain: com.atlassian.jira.issue.fields.rest.json.beans.CommentJsonBean["body"])
I was able to create a comment using markup by passing a string formatted according to the documentation here. For a test I created an issue and added a comment to add a two column 1 row (+ header row) table with:
comment = jira.add_comment(issue, "||header1||header2||\n|one|two|")
Which produced:
Make sure to wrap your comment string in double quotes.

Paginated request using python-asana API

I am trying to export all tasks from all of my asana work-spaces using python-asana API. But at some point it exists after giving the following error message.
Traceback (most recent call last):
File "export.py", line 56, in <module>
for index, task in enumerate(tasks):
File "build\bdist.win32\egg\asana\page_iterator.py", line 58, in items
File "build\bdist.win32\egg\asana\page_iterator.py", line 54, in next
File "build\bdist.win32\egg\asana\page_iterator.py", line 43, in __next__
File "build\bdist.win32\egg\asana\page_iterator.py", line 74, in get_next
File "build\bdist.win32\egg\asana\client.py", line 104, in get
File "build\bdist.win32\egg\asana\client.py", line 75, in request
asana.error.InvalidRequestError: Invalid Request: Your pagination token has expired.
I read that to solve this we need to make paginated requests. But I tried passing only offset to my request as following:
tasks = client.tasks.find_all({'project' : project['id']}, limit=50)
But, there was no difference as I was not getting any 'next_page' value even though there was more than 50 tasks in the project.
So my question is:
How can I do paginated request using python-asana API? An explanation with an example would be best!
EDIT:
I am fetching the tasks as below:
tasks = client.tasks.find_all({'project' : project['id']}, item_limit=1)
print "Tasks", tasks # Prints generator object
for index, task in enumerate(tasks):
complete_task = client.tasks.find_by_id(task["id"])
print complete_task #Prints complete task dictionary
Now My question is where will I get the next_page content for the remaining tasks and how do I access it.

Resources