Python 'requests' module and encoding? - python

I am doing a simple POST request using the requests module, and testing it against httpbin
import requests
url = 'http://httpbin.org/post'
params = {'apikey':'666666'}
sample = {'sample': open('test.bin', 'r')}
response = requests.post( url, files=sample, params=params, verify=False)
report_info = response.json()
print report_info
I have an issue with the encoding. It is not using application/octet-stream and so the encoding is not correct. From the headers, I see:
{
u'origin': u'xxxx, xxxxxx',
u'files': {
u'sample': u'data:None;base64,qANQR1DBw..........
So, I get data:None instead of data:application/octet-stream when I try with curl. The file size and encoding is incorrect.
How can I force or check that it is using application/octet-stream?

Sample taken from http://www.python-requests.org/en/latest/user/quickstart/#custom-headers
>>> import json
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> headers = {'content-type': 'application/json'}
>>> r = requests.post(url, data=json.dumps(payload), headers=headers)
You might want to change the headers to
headers = {'content-type': 'application/octet-stream'}
response = requests.post( url, files=sample, params=params, verify=False,
headers = headers)

Related

python dynamic value in api payload

Hey i have an api request and i need the value in payload to by dynamic, i tried with f'' but it wont make it dynamic
will appreciate your help.
import requests
url = "https://www.stie.com/api/conversations/KJQ-CZHNR-985/fields"
valuetarget = "123"
payload = {'apikey': 'zbyc88srdi333d3dpq5lye48pgg1tfo1pnjvj65ld',
'customfields': '[{"code": "orderno", "value":"valuetarget"}]'}
files = [
]
headers = {}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
You just need to load json and dump it to string and send it.
import json
valuetarget = "123"
payload = {
'apikey': 'zbyc88srdi333d3dpq5lye48pgg1tfo1pnjvj65ld',
'customfields':
json.dumps([{"code": "orderno", "value":valuetarget}])
}
You should escape the curly braces in the formatted string, like so:
f'[{{"code": "orderno", "value":"{valuetarget}"}}]'
But why not let requests format the string for you?
import requests
url = "https://www.stie.com/api/conversations/KJQ-CZHNR-985/fields"
valuetarget = "123"
# 'customfields' is now a list of dictionaries
payload = {'apikey': 'zbyc88srdi333d3dpq5lye48pgg1tfo1pnjvj65ld',
'customfields': [{"code": "orderno", "value": valuetarget}]}
files = [
]
headers = {}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)

How to convert http request to Python?

I need your help.
I am looking to communicate with a REST API containing sensor data at port number 3.
I have a Json (POST) request that works perfectly executed on a REST client like Insomnia.
My request :
{ "header": { "portNumber": 3 }, "data": { "index": 40 } }
Picture of my request
However I am unable to make it work on Python and to recover data from my sensor.
My Python code :
import requests
import json
url = 'http://192.168.1.100/iolink/sickv1' # Address of the OctoPrint Server
header = {'portNumber': '3', 'Content-Type': 'application/json'} #Basic request's header
data = {'index': 40}
def get_sensor_measure():
r = requests.post(url + '/readPort', headers=header, data=data)
print(r.content)
print(r.status_code)
I get the error:
b'{"header":{"status":1,"message":"Parsing Failed"}}'
Thank you in advance
You should pass 'portNumber': '3' in data not in header:
header = {'Content-Type': 'application/json'}
data = {'header': {'portNumber': '3'}, 'data': {'index': 40}}
And also as Karl stated in his answer you need to changes data to json:
r = requests.post(url + '/readPort', headers=header, json=data)
My guess would be that you are using the wrong field to pass your payload. It isn't really obvious, but the requests package expects JSON-type payload to be sent with the json field, not the data field, i.e.:
r = requests.post(url + '/readPort', headers=header, json=data)
With a few changes (Bold), it works. Thanks
url = 'http://192.168.1.100/iolink/sickv1' # Address of the OctoPrint Server
header = {'Content-Type': 'application/json'} #Basic request's header
**data = {'header': {'portNumber': 3}, 'data': {'index': 40}}**
def get_sensor_measure():
r = requests.post(url + '/readPort', headers=header, json=data)
print(r.content)
print(r.status_code)

Converting list to python array [duplicate]

I need to POST a JSON from a client to a server. I'm using Python 2.7.1 and simplejson. The client is using Requests. The server is CherryPy. I can GET a hard-coded JSON from the server (code not shown), but when I try to POST a JSON to the server, I get "400 Bad Request".
Here is my client code:
data = {'sender': 'Alice',
'receiver': 'Bob',
'message': 'We did it!'}
data_json = simplejson.dumps(data)
payload = {'json_payload': data_json}
r = requests.post("http://localhost:8080", data=payload)
Here is the server code.
class Root(object):
def __init__(self, content):
self.content = content
print self.content # this works
exposed = True
def GET(self):
cherrypy.response.headers['Content-Type'] = 'application/json'
return simplejson.dumps(self.content)
def POST(self):
self.content = simplejson.loads(cherrypy.request.body.read())
Any ideas?
Starting with Requests version 2.4.2, you can use the json= parameter (which takes a dictionary) instead of data= (which takes a string) in the call:
>>> import requests
>>> r = requests.post('http://httpbin.org/post', json={"key": "value"})
>>> r.status_code
200
>>> r.json()
{'args': {},
'data': '{"key": "value"}',
'files': {},
'form': {},
'headers': {'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'close',
'Content-Length': '16',
'Content-Type': 'application/json',
'Host': 'httpbin.org',
'User-Agent': 'python-requests/2.4.3 CPython/3.4.0',
'X-Request-Id': 'xx-xx-xx'},
'json': {'key': 'value'},
'origin': 'x.x.x.x',
'url': 'http://httpbin.org/post'}
It turns out I was missing the header information. The following works:
import requests
url = "http://localhost:8080"
data = {'sender': 'Alice', 'receiver': 'Bob', 'message': 'We did it!'}
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
r = requests.post(url, data=json.dumps(data), headers=headers)
From requests 2.4.2 (https://pypi.python.org/pypi/requests), the "json" parameter is supported. No need to specify "Content-Type". So the shorter version:
requests.post('http://httpbin.org/post', json={'test': 'cheers'})
Which parameter between data / json / files you need to use depends on a request header named Content-Type (you can check this through the developer tools of your browser).
When the Content-Type is application/x-www-form-urlencoded, use data=:
requests.post(url, data=json_obj)
When the Content-Type is application/json, you can either just use json= or use data= and set the Content-Type yourself:
requests.post(url, json=json_obj)
requests.post(url, data=jsonstr, headers={"Content-Type":"application/json"})
When the Content-Type is multipart/form-data, it's used to upload files, so use files=:
requests.post(url, files=xxxx)
The better way is:
url = "http://xxx.xxxx.xx"
data = {
"cardno": "6248889874650987",
"systemIdentify": "s08",
"sourceChannel": 12
}
resp = requests.post(url, json=data)
headers = {"charset": "utf-8", "Content-Type": "application/json"}
url = 'http://localhost:PORT_NUM/FILE.php'
r = requests.post(url, json=YOUR_JSON_DATA, headers=headers)
print(r.text)
Works perfectly with python 3.5+
client:
import requests
data = {'sender': 'Alice',
'receiver': 'Bob',
'message': 'We did it!'}
r = requests.post("http://localhost:8080", json={'json_payload': data})
server:
class Root(object):
def __init__(self, content):
self.content = content
print self.content # this works
exposed = True
def GET(self):
cherrypy.response.headers['Content-Type'] = 'application/json'
return simplejson.dumps(self.content)
#cherrypy.tools.json_in()
#cherrypy.tools.json_out()
def POST(self):
self.content = cherrypy.request.json
return {'status': 'success', 'message': 'updated'}
With current requests you can pass in any data structure that dumps to valid JSON , with the json parameter, not just dictionaries (as falsely claimed by the answer by Zeyang Lin).
import requests
r = requests.post('http://httpbin.org/post', json=[1, 2, {"a": 3}])
this is particularly useful if you need to order elements in the response.
I solved it this way:
from flask import Flask, request
from flask_restful import Resource, Api
req = request.json
if not req :
req = request.form
req['value']
It always recommended that we need to have the ability to read the JSON file and parse an object as a request body. We are not going to parse the raw data in the request so the following method will help you to resolve it.
def POST_request():
with open("FILE PATH", "r") as data:
JSON_Body = data.read()
response = requests.post(url="URL", data=JSON_Body)
assert response.status_code == 200

Google calendar- get modified events with nextSyncToken via API rest

Can anyone please tell me how to write a cURL to get events (only modified) list with nextSyncToken?
This is my code that's not working:
def get_headers():
headers = {
#'Content-Type': "application/json",
'Authorization': access_token_json
}
return headers
def get_nexttokensync_list_event():
url_get_list_event = "https://www.googleapis.com/calendar/v3/calendars/id#gmail.com/events"
querystring = {"nextSyncToken": "CMCEh************jd4CGAU="}
response = requests.request("GET", url_get_list_event, headers=headers, params=querystring)
json_event_list_formatted = response.text
print(json_event_list_formatted)
Yes, i've done it!
Here is my code:
import requests
url = "https://www.googleapis.com/calendar/v3/calendars/here_calendar_id/events"
querystring = {"syncToken":"here_token"}
headers = {
'Content-Type': "application/json",
}
response = requests.request("GET", url, headers=headers, params=querystring)
print(response.text)

REST post using Python-Request

Why doesn't this simple code POST data to my service:
import requests
import json
data = {"data" : "24.3"}
data_json = json.dumps(data)
response = requests.post(url, data=data_json)
print response.text
And my service is developed using WCF like this :
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/test", ResponseFormat =
WebMessageFormat.Json,RequestFormat=WebMessageFormat.Json)]
string test(string data );
Note: If is remove the input parameter data everything works fine, what may be the issue.
You need to set the content type header:
data = {"data" : "24.3"}
data_json = json.dumps(data)
headers = {'Content-type': 'application/json'}
response = requests.post(url, data=data_json, headers=headers)
If I set url to http://httpbin.org/post, that server echos back to me what was posted:
>>> import json
>>> import requests
>>> import pprint
>>> url = 'http://httpbin.org/post'
>>> data = {"data" : "24.3"}
>>> data_json = json.dumps(data)
>>> headers = {'Content-type': 'application/json'}
>>> response = requests.post(url, data=data_json, headers=headers)
>>> pprint.pprint(response.json())
{u'args': {},
u'data': u'{"data": "24.3"}',
u'files': {},
u'form': {},
u'headers': {u'Accept': u'*/*',
u'Accept-Encoding': u'gzip, deflate, compress',
u'Connection': u'keep-alive',
u'Content-Length': u'16',
u'Content-Type': u'application/json',
u'Host': u'httpbin.org',
u'User-Agent': u'python-requests/1.0.3 CPython/2.6.8 Darwin/11.4.2'},
u'json': {u'data': u'24.3'},
u'origin': u'109.247.40.35',
u'url': u'http://httpbin.org/post'}
>>> pprint.pprint(response.json()['json'])
{u'data': u'24.3'}
If you are using requests version 2.4.2 or newer, you can leave the JSON encoding to the library; it'll automatically set the correct Content-Type header for you too. Pass in the data to be sent as JSON into the json keyword argument:
data = {"data" : "24.3"}
response = requests.post(url, json=data)

Categories

Resources