Python required list parameter is not present - python

I'm trying to imitate the following cURL command to POST my url-encoded list to a form:
curl "https://website.com/update/" --data "simChangesList=%5B%7B%22simId%22%3A760590802%2C%22changeType%22%3A2%2C%22targetValue%22%3A%220003077%22%2C%22effectiveDate%22%3Anull%7D%5D" --compressed
The data I need to url-encode is the simChangesList. Essentially, this data is decoded as simChangesList: [{"simId":760590802,"changeType":2,"targetValue":000307,"effectiveDate":null}]
With the following script, I come across a Required List parameter 'simChangesList' is not present error.
Here's my script:
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
enc = urllib.quote('simChangesList: [{"simId":760590802,"changeType":2,"targetValue":000307,"effectiveDate":null}]')
auth = session.post(uri, data=enc, headers=headers)
print auth.text
However, executing the above script returns the above missing list parameter error.
How can I pass in the missing list parameter when my encoded list looks like this:
simChangesList%3A%20%5B%7B%22simId%22%3A760590802%2C%22changeType%22%3A2%2C%22targetValue%22%3A000307%2C%22effectiveDate%22%3Anull%7D%5D
Notice it's missing the '=' operator, why can I not execute my script and make it closely resemble my cURL command to post my url-encoded information?

I also encountered a similar situation landlord, but I just prompted one of the parameters inside json does not exist, is looking for a solution.
On the landlord to pass parameters, it is recommended to add a json.dumps (data)
try it.

Related

python request with authentication access token

I am trying to get an API query into python. The command line
curl -X POST https://xxxx.com/api/auth/refreshToken -d access_token
it will give output in text string.access_tokenis a hexadecimal variable that remains constant throughout. I would like to make this call from python so that I can loop through different ids and analyze the output. Any ideas?
Many thanks.
You can use requests library https://2.python-requests.org/en/master/user/quickstart/#make-a-request
Maybe something like this :
response = requests.post('https://httpbin.org/post', data = {'key':'value'})
Then you can utilise the response and process it

Getting "INVALID_TOKEN_FORMAT The security token format does not conform to expected schema." docusign legacy auth header

I'm trying to write a request using Python Requests which sends a request to Docusign. I need to use the legacy authorization header, but unfortunately it seems most documentation for this has been removed. When I send the request I get an error as stated in the title.
From research, I found that special characters in the password can cause this issue, so I've confirmed that my password has no special characters, and that my API key is correct. I am currently sending the header as a stringified dictionary as shown below. I have tried it several other ways, and this seems to be the closest, but it still results in the error. Other ways I've tried include attempting to write out the header as a single string (not forming a dictionary first), but that didn't seem to work any better.
docusign_auth_string = {}
docusign_auth_string["Username"] = docusign_user
docusign_auth_string["Password"] = docusign_password
docusign_auth_string["IntegratorKey"] = docusign_key
docusign_auth_string = str(docusign_auth_string)
headers = {'X-DocuSign-Authentication': docusign_auth_string}
response = requests.post(docusign_url, headers=headers, data=body_data)
The above code returns a 401 with the message, INVALID_TOKEN_FORMAT "The security token format does not conform to expected schema." The header I am sending looks as follows:
{'X-DocuSign-Authentication': "{'Username': 'test#test.com', 'Password': 'xxxxxxxxxx', 'IntegratorKey': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'}"}
When I send the request via Postman, it works just fine. In Postman I enter the header name as X-Docusign-Authentication, and the value as: {"Username":"{{ds_username}}","Password":"{{ds_password}}","IntegratorKey":"{{ds_integrator_key}}"} (subbing the same variable values as in the python code).
Therefore it definitely has something to do with the way Requests is sending the header.
Does anyone know why I might be getting the above error?
I'm able to reproduce this behavior: It looks like DocuSign doesn't accept Single Quotes around the sub-parameters of the x-DocuSign-Authentication header value.
Your example fails:
{'Username': 'test#test.com', 'Password': 'xxxxxxxxxx', 'IntegratorKey': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'}
This has more success:
{"Username": "test#test.com", "Password": "xxxxxxxxxx", "IntegratorKey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}
I'm not familiar enough with Python to advise if there's a different code structure you can follow to use double quotes instead of single. Worst case scenario, you may need to manually set the Header Value to follow that format.
I found a solution to this issue. The response that mentioned double quotes is correct, but in Python I was unable to send a string with the proper format for docusign to understand. Next I found the following Stack overflow question, which ultimately provided the solution:
How to send dict in Header as value to key 'Authorization' in python requests?
I used json.dumps and that resolved the issue. My code is as follows:
docusign_auth_string = {}
docusign_auth_string["Username"] = docusign_user
docusign_auth_string["Password"] = docusign_password
docusign_auth_string["IntegratorKey"] = docusign_key
headers = {"X-DocuSign-Authentication": json.dumps(docusign_auth_string), "Content-Type": "application/json"}
Since you are having success using Postman, it will help to get exactly what is being sent via your request. For this use:
response = requests.get(your_url, headers=your_headers)
x = response.request.headers()
print(x)
This will show you exactly what requests is preparing and sending off. If you post that response here id be happy to help more.
How can I see the entire HTTP request that's being sent by my Python application?
The 2nd answer shows all the possible parameters of your response object.

Python Requests - add text at the beginning of query string

When sending data through python-requests a GET request, I have a need to specifically add something at the beginning of the query string. I have tried passing the data in through dicts and json strings with no luck.
The request as it appears when produced by requests:
/apply/.../explain?%7B%22......
The request as it appears when produced by their interactive API documentation (Swagger):
/apply/.../explain?record=%7B%22....
Where the key-value pairs of my data follow the excerpt above.
Ultimately, I think the missing piece is the record= that gets produced by their documentation. It is the only piece that is different from what is produced by Requests.
At the moment I've got it set up something like this:
import requests
s = requests.Session()
s.auth = requests.auth.HTTPBasicAuth(username,password)
s.verify = certificate_path
# with data below being a dictionary of the values I need to pass.
r = s.get(url,data=data)
I am trying to include an image of the documentation below, but don't yet have enough reputation to do so:
apply/model/explain documentation
'GET' requests don't have data, that's for 'POST' and friends.
You can send the query string arguments using params kwarg instead:
>>> params = {'record': '{"'}
>>> response = requests.get('http://www.example.com/explain', params=params)
>>> response.request.url
'http://www.example.com/explain?record=%7B%22'
From the comments i felt the need to explain this.
http://example.com/sth?key=value&anotherkey=anothervalue
Let's assume you have a url like the above in order to call with python requests you only have to write
response = requests.get('http://example.com/sth', params={
'key':'value',
'anotherkey':'anothervalue'
})
Have in mind that if your value or your keys have any special character in them they will be escaped thats the reason for the %7B%2 part of url in your question.

CherryPy only receiving 1st query string parameter

I've just begun my journey into the realms of the CherryPy module in Python. It's pretty awesome how easy it makes it to setup a server with a RESTful api, however I've ran into an issue. My code is only acknowledging the first parameter in a query string.
I want to make a GET request like so:
curl -X GET 127.0.0.1:8080/api/sum/?a=2&b=3
My Python code is as follows:
import cherrypy
class getSum:
exposed = True
def GET(self, **params):
a = float(params['a'])
b = float(params['b'])
return a+b
if __name__ == '__main__':
cherrypy.tree.mount(getSum(), '/api/sum/', {'/': {'request.dispatch': cherrypy.dispatch.MethodDispatcher()}})
cherrypy.engine.start()
cherrypy.engine.block()
After fiddling with the code for a while I've come to the following diagnosis:
When the query string is being read into params, instead of starting a new entry in the dictionary when it reaches the '&' it just stops instead.
Has anyone got any advice on how to read multiple parameters in as a single query string?
With Thanks, Sean.
The Python script posted in my question is actually a working implementation of what I wanted to do. The problem was instead with the curl request that I was making.
The '&' character in my curl request was truncating my bash command, resulting in this: curl -X GET 127.0.0.1:8080/api/sum/?a=2
The fix for this is to wrap my url in quotes like so: curl -X GET "127.0.0.1:8080/api/sum/?a=2&b=3"
When executing this command 5.0 is returned to the terminal, as expected.
This following post contains a useful discussion on the use of ampersands in curl requests: How to include an '&' character in a bash curl statement

Flask not recognising two URL parameters

I'm trying to send two parameters to a URL routed with Flask.
If I do:
curl -i http://127.0.0.1:5000/api/journeys/count?startStationName=Hansard%20Mews,%20Shepherds%20Bush&endStationName=Farringdon%20Lane,%20Clerkenwell
Then my code which is:
#application.route('/api/journeys/count', methods=['GET'])
def journeys():
print request.args
startStationName = request.args.get('startStationName')
endStationName = request.args.get('endStationName')
Should print a dict with startStationName and endStationName defined.
However, instead, only the first parameter seems to be received:
ImmutableMultiDict([('startStationName', u'Hansard Mews, Shepherds Bush')])
Anybody got any idea what I'm doing wrong? I have a feeling there must be some kind of stupid mistake or misunderstanding somewhere but I've been looking for an hour and can't find it.
Your shell interprets the & as a put the command in the background character. To prevent this, quote the whole URL:
curl -i "http://127.0.0.1:5000/api/journeys/count?startStationName=Hansard%20Mews,%20Shepherds%20Bush&endStationName=Farringdon%20Lane,%20Clerkenwell"

Categories