I'm trying to create a new list from an API return in python. The purpose of this API call is to pull a list of driver's names, and pair them to a vehicle ID native to the API service. The code currently looks like this:
url = url
headers = {
"accept": "application/json",
"authorization": auth
}
response = requests.get(url, headers=headers)
response = response.json()
for doc in response['data']:
try:
doc['id'],
doc['staticAssignedDriver']['name']
except:
pass
else:
names = {
doc['staticAssignedDriver']['name']: doc['id']
}
names.update(names)
print(type(names))
print(names)
This prints a list of unique names and id's as individual dicts. IE:
{'name1':'id1'}
<class 'dict'>
{'name2':'id2'}
<class 'dict'>
Until I have all of my name:id pairs from my API.
But I'd like to make that a single dict, as such:
{'name1': 'id1', 'name2': 'id2'}
It seems like each new name/id pair ends up being its own var 'names'. Is there a way to make this its own singular dict, instead of individual?
When you do names = {whatever: whatever}, you always create a new dictionary with exactly one key and value. If you want to have only one dictionary that you update over and over, create the dictionary outside of the loop, and just assign a single value into it at a time:
names = {}
for doc in ...:
...
names[doc['staticAssignedDriver']['name']] = doc['id']
x = [{'name1':'id1'},
{'name2':'id2'}]
d = {}
for dct in x:
d.update({key: value for key, value in dct.items()})
print(d)
{'name1': 'id1', 'name2': 'id2'}
I have a list of lists in this format:
nrows = ["['Shock pain', 'attack sharp pain']",
"['bruises', 'lump']",
"['fever', 'cold', 'Anxiety']",
"['neck pain', 'headache']"]
I want to call an API by passing everytime 1 list at a time from the nrows list. Each list should be passed 1 by 1 to the data dict with key sList and the response should be saved.
The API function is as follows:
newres = []
for i in nrows:
url = "https://testabcd.io"
data= {
"sList": i,
"kList" : ["age"],
}
headers = {
'Content-Type': 'application/json',
'Auth': '0644427814339900'
}
response = requests.request("GET", url, headers=headers, json=data)
newres.append(response.text)
print(response.text)
print(newres)
Inside the data dict, in sList, at each iteration, I want to pass 1 sublist at a time and get the response appended in a list.
The current code has all the response same as I think I am unable to iterate and change the value of the data dict with key sList which is what is expected.
The csv looks like this:
['Shock pain', 'attack sharp pain']
['bruises', 'lump']
['fever', 'cold', 'Anxiety']
Assuming the file you work with, really looks like this:
['Shock pain', 'attack sharp pain']
['bruises', 'lump']
['fever', 'cold', 'Anxiety']
you can use ast.literal_eval in order to convert the line from the file into list
import requests
from ast import literal_eval
newres = []
url = "https://testabcd.io"
headers = {'Content-Type':'application/json',
'Auth':'0644427814339900'}
with open("yourfile") as f:
for line in f:
data= {"sList": literal_eval(line),
"kList" : ["age"]}
response = requests.get(url, headers=headers, json=data)
newres.append(response.text)
print(response.text)
print(newres)
Note:
This is not tested.
Given that your data comes from non-standard file, where they were exported in bad manner from a dataframe, created unknown how - I would suggest that you seriously reconsider all your workflow and how you manipulate your data.
Code below works:
r = requests.post(url = myurl, data = '{"title":"sometitle", "body":"some body"}')
But this code doesn't work:
t = "title"
b = "body"
r = requests.post(url = myurl, data = '{"title":title, "body":body}')
The second one causes 400 error.
I can't find any meaningful difference.
What I changed is just replacing " " string to a string value.
According to requests doc, data is
data – (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the Request.
I have to get some values and store them into variables, so I need to make the code in the second way.
How can I resolve this?
data – (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the Request.
In both cases you are not passing a dictionary. You are passing a string both times.
r = requests.post(url = myurl, data = '{"title":"sometitle", "body":"some body"}')
This is a dictionary parsed into a string.
t = "title"
b = "body"
r = requests.post(url = myurl, data = '{"title":title, "body":body}')
This is a non-valid dictionary parsed into a string. You probably meant to write:
t = "title"
b = "body"
r = requests.post(url = myurl, data = {"title":title, "body":body})
Which is equivalent to:
r = requests.post(url = myurl, data = {"title":"title", "body":"body"})
Here you would be passing a dictionary and you can also reference variables. It is not a string you are passing.
If you require the data to be in a string format (which doesn't make sense since the documentation you referenced says it requires a dictionary) you do:
t = "title"
b = "body"
r = requests.post(url = myurl, data = json.dumps({"title":title, "body":body}))
I have this method:
import requests
import json
data = {
"postcodes" : ["AL1 2RJ", "AL9 5JP", "BN14 9GB", "BN16 3RT", "BN23 6QD", "BN3 7PN", "BN9 0AG", "BR5 3RP", "CM2 6XE","CM20 2SX","CR0 4NX","CT1 1DX",
"CT1 3TQ", "CT10 2RQ", "CT16 3PS", "CT19 5SY", "DA1 4LD", "DA11 0DQ", "E4 8JA", "E6 6LG", "EN1 1TH", "EN9 1BY", "GU14 7QL", "GU19 5DG", "GU22 8BD",
"GU34 2QS","GU7 1DR", "GU9 9QJ", "HA4 0LN", "HP11 1FY", "HP20 1DH", "HP3 9AA", "IG2 6BE", "KT12 2SS", "KT14 7NP", "LU1 3JH", "LU5 4XZ",
"ME10 2XD", "ME20 7TP", "ME5 9SQ", "ME8 0PU", "MK1 1BN", "MK18 1TB", "N11 3PW", "NW1 9EX", "NW9 7TH", "PO19 7YH", "PO22 9NF", "PO3 5LZ",
"PO9 1ND", "RG12 1EN", "RG2 0HB", "RG22 4TT", "RG30 1PR", "RG40 2NU", "RG41 5HH", "RH1 6QL", "RH11 7ST", "RH12 1HR", "RH15 9QT", "RH19 1QL",
"RM20 3LP", "RM7 0AN", "RM9 6SJ", "SE1 5BA", "SE10 8DA", "SE26 4PU", "SE28 8RD", "SE7 7TZ", "SE9 5LT", "SG13 7RQ", "SL1 4XB", "SL6 1AY",
"SS1 1PA", "SS13 3BY", "SS14 3AF", "SS2 6FW", "SS67UP", "SW11 3RX", "SW17 0BW", "SW20 0JQ", "TN14 5EW", "TN2 3FB", "TN23 7DH", "TN37 7PB",
"TN40 2JS", "TW13 4EX", "TW8 8JW", "TW9 1YB", "UB4 0TU", "UB6 0UW", "UB8 2TE", "WD17 2SF", "WD6 4PR"]
}
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
resp = requests.post('https://api.postcodes.io/postcodes/', data=data, headers=headers)
print(resp.json())
I run this python myscript.py < myfile.json
{'status': 400, 'error': 'Invalid JSON submitted. You need to submit a JSON object with an array of postcodes or geolocation objects. Also ensure that Content-Type is set to application/json'}
But the request seems to be fine, this is what the postcodes.io doc says:
Bulk Postcode Lookup
Accepts a JSON object containing an array of postcodes. Returns a list of matching postcodes and respective available data.
Be sure to submit JSON requests setting Content-Type to application/json
Accepts up to 100 postcodes.
POST
https://api.postcodes.io/postcodes
Post Data
This method requires a JSON object containing an array of postcodes to be posted, e.g.
{
"postcodes" : ["PR3 0SG", "M45 6GN", "EX165BL"]
}
This is the doc page
The query seems to be fine, any ideas?
You just have to replace data=data with json=data. So that it can be verify against content-type=application/json.
resp = requests.post('https://api.postcodes.io/postcodes/', json=data, headers=headers)
it will work.
So I had pretty similar problem, and I was struggling to transform a dataframe column into a list then into a json object. The solution might be pretty obvious, but I got lost in json.dumps() and that is not the solution. The following worked:
import json
import requests
import pandas as pd
#imagine you have a csv, excel where you have the postcodes
create_sample={'Postcode': ['OL67UB', 'AB101QS']}
df_postcodes=pd.DataFrame(create_sample)
list_postcodes=list(df_postcodes['Postcode'])
data = {
"postcodes" : list_postcodes
}
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
resp = requests.post('https://api.postcodes.io/postcodes/', json=data, headers=headers)
print(resp.json())
I have a function which require to pass some ids as comma seperated to the url string.
My code:
def shipment(self, orderItemIds):
url = "https://api.flipkart.net/sellers/orders/shipments"
payload = {'orderItemsIds':orderItemIds}
return self.session.get(url, data=payload)
I need to pass id1, id2, id3 so that i get a link as:
https://api.flipkart.net/sellers/orders/shipments?orderItemsIds={id1,id2...}
I tried to pass it as a string. and as a list too. But it didn't worked.
oid = 'id1,id2,id3' # or
oid = ['id1',id2'','id3']
How to do it?
I passed an id as oiids = '230501592'.
On running response.url, it gives me:
https://api.flipkart.net/sellers/orders/shipments?orderItemsIds
It shows that parameter values are not passing in the url string.
I believe what you want is this (where orderItemIds is a list of strings):
def shipment(self, orderItemIds):
url = "https://api.flipkart.net/sellers/orders/shipments"
params = {'orderItemsIds': ','.join(orderItemIds)}
return self.session.get(url, params=params)
The differences from the version you have in the question are that orderItemIds is assumed to be a list of strings and is being joined with commas, and the data keyword is replaced with params, which is the right choice for a GET request.
You can easily send get parameters in python requests library-
data = {
'orderItemsIds': ['id1', 'id2', 'id3']
}
response = requests.get(url, data = data)