I'm trying to pass a variable to the data field in requests.post() and I continue to get the error,
Error Response: {'error': {'message': 'Exception while reading request',
'detail': 'Cannod decode: java.io.StringReader#1659711'}, 'status': 'failure'}
Here is my code
#Fill array from CSV
temp=[]
for row in csv.iterrows():
index, data = row
temp.append(data.tolist())
#Create new asset for all assets in CSV
for index, row in enumerate(temp):
make = temp[index][0]
serial = str(temp[index][1])
date = str(temp[index][2])
response = requests.post(url, auth=(user, pwd), headers=headers,
data='{"asset_tag":"test1", "assigned_to":"test2",
"company":"test3", "serial_number":serial}')
I originally tried feeding it directly from the CSV using
str(temp[index][1])
This did not work, so I tried assigning str(temp[index][1]) to the variable serial and then passing the variable like that but that also results in the same error.
A point in the right direction would be great, thanks!
Instead of sending the request payload body in string, pass it in json form.
requests.post accepts string in data variable and json in json variable. I faced a same issue while trying to make my first REST call to ServiceNow instance via Python. Hope this helps.
response = requests.post(url, auth=(user, pwd), headers=headers,
json={"asset_tag":"test1", "assigned_to":"test2",
"company":"test3", "serial_number":serial})
Remove the single quotes from the following :
data='{"asset_tag":"test1", "assigned_to":"test2",
"company":"test3", "serial_number":serial}'
Use
data = {"asset_tag":"test1", "assigned_to":"test2",
"company":"test3", "serial_number":serial}
rather than passing data=data, take data as dict and pass it as json=data.
Related
While trying to connect to an API from Alpaca (a broker that accepts automated orders), I found that I was unable to send data with the requests.delete method. Here is some code:
def close_position(symbol, percentage, api_key=api_key, secret_key=secret_key, base_url=base_url):
data = {"percentage": percentage}
headers = {
"APCA-API-KEY-ID": api_key,
"APCA-API-SECRET-KEY": secret_key
}
url = f"{base_url}/v2/positions/{symbol}"
order = requests.delete(url, json=data, headers=headers)
return order.json()
This code is supposed to close (i.e., liquidate) a specified percentage of a position. However, it seems that the data sent using the delete method is disregarded; this function always closes my entire position instead of the specified percentage. Here is the documentation for the Alpaca API: https://alpaca.markets/docs/api-references/trading-api/positions/#close-a-position
I have also tried the data and params parameter and json.dumps(data), but to no avail.
Any idea how to send data with the requests.delete method would be appreciated.
I am trying to add a feature to the Dataset via Mapbox API using Python. I'm following this instruction https://docs.mapbox.com/api/maps/#update-a-dataset but keep getting this error:
{'message': 'Provide a single Feature to insert'}
The code looks like this:
rs = []
dictionary = {
"id":1,
"type":"Feature",
"properties":{},
"geometry":{"coordinates":[-83.750246, 42.269375],"type":"Point"}}
url = "https://api.mapbox.com/datasets/v1/voratima/"+dataset+"/features/1?access_token="+access_token
rs.append(grequests.put(url, data=dictionary, hooks = {'response' : do_something}))
grequests.map(rs, exception_handler=exception_handler)
I've tried the following but none of them work:
using requests instead of grequests
wrapping the dictionary with json.dumps()
changing the put parameter from data=dictionary to json=dictionary
Making sure the id for both data and URL are set to 1.
Postman of the exact same request does not have the error. What am I missing?
Given a dataset with dataset ID dataset exists, your request body looks ok.
Please add the header
headers = {'Content-type': 'application/json'}
Also can you check if you meet these specs:
This should be one individual GeoJSON feature, not a GeoJSON
FeatureCollection. If the GeoJSON feature has a top-level id property,
it must match the feature_id you use in the URL endpoint.
It turns out I forgot the header. Thanks to Mortiz for pointing that out. After the update I got
<Response [400]> {'message': 'Unexpected token i'}
That's because I need to wrap the dictionary inside json.dumps(). Then the error became
<Response [422]> {'message': 'Request URI does not match feature id'}
That's because the id in the dictionary has to be a string i.e. "id":"1" not "id":1. Here's the code that works:
rs = []
dictionary = {
"id":"1",
"type":"Feature",
"properties":{},
"geometry":{"coordinates":[-83.750246, 42.269375],"type":"Point"}}
headers = {'Content-type': 'application/json'}
url = "https://api.mapbox.com/datasets/v1/voratima/"+dataset+"/features/1?access_token="+access_token
rs.append(grequests.put(url, data=json.dumps(dictionary), headers=headers, hooks = {'response' : do_something}))
grequests.map(rs, exception_handler=exception_handler)
Hello everyone here is a snippet of my nested json Response.
https://pastebin.com/qTk21iwX
What I want to accomplished to get all the "Row" data from this json response but I have yet to figure out the correct method of approaching this.
This is what I have tried is:
response = requests.get(url, headers=headers, json={"script": sql}, verify=verify).json()
print(response)
responseobject = json.dumps(response)
print(responseobject)
for object in responseobject['Result']['Results']:
print (object)
My output after running this code
TypeError: string indices must be integers
Any suggestions ?
responseobject = json.dumps(response)
Here you are turning the response object into a string. So when you do responseobject['Result'], you are indexing a string, not a dictionary.
To fix the problem, just remove responseobject = json.dumps(response) and do response['Result']['Results'] instead of responseobject['Result']['Results'].
I'm connecting to a login protected API with a Python script here below.
import requests
url = 'https://api.json'
header = {'Content-Type': 'application/x-www-form-urlencoded'}
login = ('kjji#snm.com', 'xxxxx')
mnem = 'inputRequests':'{'inputRequests':'[{'function':'GDSP','identifier':'ibm','mnemonic':'IQ_TOTAL_REV'}]}}
r = requests.post(url, auth=login, data=mnem, headers=header)
print(r.json())
The connection is established but I am getting an error from the API because of the format of the data request.The original format is here below. I cannot find a way to enter this in the mnem here above:
inputRequests={inputRequests:
[
{function:"xxx",identifier:"xxx",mnemonic:"xxx"},
]
}
The error given is
C:\Users\xxx\Desktop>pie.py
File "C:\Users\xxx\Desktop\pie.py", line 6
mnem={'inputRequests':'{'inputRequests':'[{'function':'xxx','identifier':'xx','mnemonic':'xxx'}]}}
^
SyntaxError: invalid syntax
I am unsure on how to proceed from here. I cannot find anything in the requests documentation that points to how to insert several variables in the data field.
The requests module in Python receive protogenic Python dict as the JSON data in post request but not a string. Therefore, you may try to define mnem like this:
mnem = {
'inputRequests':[
{'function':'GDSP',
'identifier':'ibm',
'mnemonic':'IQ_TOTAL_REV'
}
]}
the data parameter should be a dictionary.
therefore to pass the three parameters try using:
mnem = {'function':'GDSP','identifier':'ibm','mnemonic':'IQ_TOTAL_REV'}
There is a POST request which works perfectly when I pass the data as below:
url = 'https://www.nnnow.com/api/product/details'
requests.post(url, data="{\"styleId\":\"BMHSUR2HTS\"}", headers=headers)
But when I use json.dumps() on a dictionary and send the response, I do not get the response (response code 504), using headers={'Content-Type': 'application/json'} . Have also tried json parameter of Post requests.
requests.post(url, data=json.dumps({"styleId":"BMHSUR2HTS"}), headers={'content-type': 'application/json'})
Now, the data returned by json.dumps({"styleId":"BMHSUR2HTS"}) and
"{\"styleId\":\"BMHSUR2HTS\"}" is not the same.
json.dumps({"styleId":"BMHSUR2HTS"}) == "{\"styleId\":\"BMHSUR2HTS\"}" gives False even though a print on both shows a similar string.
How can I get the same format as "{\"styleId\":\"BMHSUR2HTS\"}" from a dictionary {"styleId":"BMHSUR2HTS"} ?
If you print the json.dumps({"styleId":"BMHSUR2HTS"}), you will notice two things:
your output is a string (just try type(json.dumps({"styleId":"BMHSUR2HTS"})));
if you pay attention the output will add a space between the json name and value: {"styleId": "BMHSURT2HTS"}.
Not sure how do you want to handle this, and in your entry code, but there are 2 main options to workaround this issue:
Replace the space on json.dumps output: json.dumps({"styleId":"BMHSUR2HTS"}).replace(': ', ':')
Convert all to json by using eval(): eval(json.dumps({"styleId":"BMHSUR2HTS"})) and eval(YOUR_JSON_STRING)
I hope this helps you.