I have a request in python that calls a get endpoint and in the responses headers a Etag is returned. I am extracting this etag to use in a later json request. The etag when printed is in the following format W/"5w+V3HeRYGpkXyvO5oLhMA==". When i try post this request in the json i get a bad data request as characthers in the etag are not escaped. I have tried using re.escape() but this does not seem to be changing the format for me. If anyone can help.
response = self.client.get("https://URL", headers={'Authorization':'Token'}){'Authorization':'Token'})
Etag = response.headers["etag"]
self.client.post("https://URL", headers={'Authorization': 'Token','Content-Type': 'application/json'}, json={"etag": Etag})
Related
I am just trying to access an API through Postman and its wokring fine.The Postman header response is returning some details like below
Authentication-Token →/DwG7gAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Connection →keep-alive
Content-Length →16
Content-Type →application/json;charset=UTF-8
Date →Tue, 25 Sep 2018 17:44:01 GMT
Server →Apache-Coyote/1.1
But when I am trying to do same in Python I am just receivig the response status.(200)
How can I get the above Authentication-Token etc details like Postman in python code.
import requests
import json
url = 'https://test-orchestrator.lmig.com/baocdp/rest/login/'
headers = {"Content-Type": "application/json"}
data1 = {"username":"abc", "password":"abc"}
print("Testing authentication for Remedy test environment...")
change_response=requests.post(url,data=json.dumps(data1),headers=headers)
print(change_response)
If you print change_response, it will most likely look like this <status [200]> or something to that effect. If you want to see the contents of the response, you can use the vars response.text, response.content, or response.headers (among others) or since this is a json response, you can use the method response.json() to convert the contents of the response into a dictionary full of native Python data types.
I would reccommend x = response.json(), as the contents of your response seem to contain an auth token that you will most likely need to communicate with this device further. You can then use auth+token = x[token_key] to isolate that token.
I'm having an issue trying to decode a python dictionary sent to my server as json.
This is what I have in my application:
payload = {'status':[bathroomId,item,percentage,timestamp]}
r=requests.post(url,None,json.dumps(payload))
Here is what I do in my Flask server:
req = request.get_json()
print req['status']
When I try to print the content of req['status'], it seems like python won't recognize it as a dictionary and I get an internal server error.
I tried printing req, and I get None
What am I missing?
Unless you set the Content-Type header to application/json in your request, Flask will not attempt to decode any JSON found in your request body.
Instead, get_json will return None (which is what you're seeing right now).
So, you need to set the Content-Type header in your request.
Fortunately since version 2.4.2 (released a year ago), requests has a helper argument to post JSON; this will set the proper headers for you. Use:
requests.post(url, json=payload)
Alternatively (e.g. using requests < 2.4.2), you can set the header yourself:
requests.post(url, data=json.dumps(payload), headers={"Content-Type": "application/json"})
Here is the relevant code from Flask:
Flask only loads JSON if is_json is True (or if you pass force=True to get_json). Otherwise, it returns None.
is_json looks at the Content-Type header, and looks for application/json there.
With the firefox plugin "HttpFox" i'm getting the POST request which looks like this:
{'json':'{"command":"SEARCH","data":{"someData":"someValue","otherData":"otherData"}}'}
Now i need to send a http request build with python to get the same data as i would get via browser. See code:
headers = {'Content-type': 'application/json; charset=utf-8'}
payload = ?
req = requests.post(url, data=json.dumps(payload), headers = headers)
My problem is:
I'm not sure how to build the payload. It should be a dictionary as well, but im confused because of the POST type which is delivered with HttpFox. There are two dictionaries inside the main dictionary.
How should i handle this ?
Appreciate any help.
Ok, i found the solution:
It was necessary to build a dict like this:
valueString = """{"command":"SEARCH","data":{"someData":"someValue","otherData":"otherData"}}"""
/// the """ ensures that the whole text between """ is handled as a string.
payload = {'json': valueString}
The key 'json' requieres a string. In this case the string looks like a dictionary.
That's it.
I'm trying to make a RESTful api call in python/django with requests.post
I can get requests.get(url=url, auth=auth) to work. Similar call in the same api family for this company
I'm trying to do:
data = {'start': 13388, 'end': 133885, 'name': 'marcus0.5'}
r = requests.post(url=url, auth=auth, headers={'Accept': 'application/json'}, data=data)
and I get the following error:
>>> r.text
u'{"status":"error","errorCode":"COMMON_UNSUPPORTED_MEDIA_TYPE","incidentId":"czEtbXNyZXBvcnRzMDQuc3RhZ2V4dHJhbmV0LmFrYW1haS5jb20jMTM3NTgxMzc3MTk4NQ==","errorMessage":"The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method.. Content type \'application/x-www-form-urlencoded;charset=UTF-8\' not supported."}'
I think it has something to do with the json, but I'm not sure what and I'm not sure how to fix it. Any ideas?
Extra info [not sure if it applies]:
I imported
import requests, django
I know the the auth is correct and I tested it with the get method
You want to set the Content-Type parameter of your request to 'application/json', not the Accept parameter.
Taken from w3.org:
The Accept request-header field can be used to specify certain media types which are acceptable for the response.
Try this instead:
import json
data = {'start': 13388, 'end': 133885, 'name': 'marcus0.5'}
r = requests.post(url=url, auth=auth, data=json.dumps(data),
headers={'content-type': 'application/json'})
EDIT:
There is a little bit of confusion (for me as well) about when to send data as a dict or a json encoded string (ie. the result of json.dumps). There is an excellent post here that explains the problem. For a brief summary send a dict when the API requires form-encoded data, and a json encoded string when it requires json-encoded data.
I'm working on an API wrapper. The spec I'm trying to build to has the following request in it:
curl -H "Content-type:application/json" -X POST -d data='{"name":"Partner13", "email":"example#example.com"}' http://localhost:5000/
This request produces the following response from a little test server I setup to see exatly what headers/params etc are sent as. This little script produces:
uri: http://localhost:5000/,
method: POST,
api_key: None,
content_type: application/json,
params: None,
data: data={"name":"Partner13", "email":"example#example.com"}
So that above is the result I want my python script to create when it hits the little test script.
I'm using the python requests module, which is the most beautiful HTTP lib I have ever used. So here is my python code:
uri = "http://localhost:5000/"
headers = {'content-type': 'application/json' }
params = {}
data = {"name":"Partner13", "email":"example#exmaple.com"}
params["data"] = json.dumps(data)
r = requests.post(uri, data=params, headers=headers)
So simple enough stuff. Set the headers, and create a dictionary for the POST parameters. That dictionary has one entry called "data" which is the JSON string of the data I want to send to the server. Then I call the post. However, the result my little test script gives back is:
uri: http://localhost:5000/,
method: POST,
api_key: None,
content_type: application/json,
params: None,
data: data=%7B%22name%22%3A+%22Partner13%22%2C+%22email%22%3A+%22example%40example.com%22%7D
So essentially the json data I wanted to send under the data parameter has been urlendcoded.
Does anyone know how to fix this? I have looked through the requests documentation and cannot seem to find a way to not auto urlencode the send data.
Thanks very much,
Kevin
When creating the object for the data keyword, simply assign a variable the result of json.dumps(data).
Also, because HTTP POST can accept both url parameters as well as data in the body of the request, and because the requests.post function has a keyword argument named "params", it might be better to use a different variable name for readability. The requests docs use the variable name "payload", so thats what I use.
data = {"name":"Partner13", "email":"example#exmaple.com"}
payload = json.dumps(data)
r = requests.post(uri, data=payload, headers=headers)
Requests automatically URL encodes dictionaries passed as data here. John_GG's solution works because rather than posting a dictionary containing the JSON encoded string in the 'data' field it simply passes the JSON encoded string directly: strings are not automatically encoded. I can't say I understand the reason for this behaviour in Requests but regardless, it is what it is. There is no way to toggle this behaviour off that I can find.
Best of luck with it, Kevin.