I need to prepare input data for a API in json format.
I am using json.loads() function but it is returning data with single quotes. I have tried to convert data into strings and added double quotes but that does not help.
import json
import pandas as pd
data = pd.read_csv('..\\dummy_api_data.csv')
dict_data = data.to_dict(orient='records')
data_json_dump = json.dumps(dict_data, default='str')
json_data = json.loads(data_json_dump)
Output :- {'name': 'Shawna', 'age': 46, 'salary': 119090}
Expected Output:- {"name": "Shawna", "age": 46, "salary": 119090}
Have you tried adding the content-type json to your header
headers = {'Content-Type': 'application/json'}
response = requests.request("POST", url, headers=headers, data=json.dumps(payload))
Related
Source=["SGD"]
Destination=["USD"]
Amount=[5000]
```import requests
url = "https://api.currencyfair.com/comparisonQuotes"
payload = "{\"currencyFrom\":\"SGD\",\"currencyTo\":\"EUR\",\"type\":\"SELL\",\"amountInfo\":
{\"amount\":50000,\"scale\":2}}"
headers = {
'user-agent': "vscode-restclient",
'content-type': "application/json",
'accept': "application/json"
}
response = requests.request("POST", url, data=payload, headers=headers)
print(response.text)
I need to pass values to payload string -
payload = "{"currencyFrom":"SGD","currencyTo":"EUR","type":"SELL","amountInfo":{"amount":50000,"scale":2}}"
Need to pass values to payload using 3 list created above```
Could you please try to explain a bit more what you're after?
I suspect what you mean is that you'd like to dynamically update the values in the text payload every time you call the function to post data.
I'd usually go about doing this by creating a placeholder string then updating that by replacing placeholder values at runtime.
payload = "{\"currencyFrom\":\"#currencyFrom\",\"currencyTo\":\"#currencyTo\",\"type\":\"SELL\",\"amountInfo\": {\"amount\":#amountInfo,\"scale\":2}}"
currencyFrom = 'USD'
currencyTo = 'EUR'
amountInfo = 50000
payload = payload.replace('#currencyFrom', currencyFrom).replace('#currencyTo', currencyTo).replace('#amountInfo', amountInfo)
Looking at the API you're trying to interact with, this is a sample of what it expects:
{"currencyFrom": "EUR",
"currencyTo": "GBP",
"type": "SELL",
"amountInfo": {"amount": 100},
"ignoreFee": false}
This is a JSON object that follows a specific format, if you try and pass a list as opposed to a string in the "currencyFrom", "currencyTo" fields etc you'll get an error.
To get multiple values as responses simply conduct multiple requests to the API, for example:
payload = "{\"currencyFrom\":\"#currencyFrom\",\"currencyTo\":\"#currencyTo\",\"type\":\"SELL\",\"amountInfo\": {\"amount\":#amountInfo,\"scale\":2}}"
currencyFrom = ['USD', 'GBP']
currencyTo = ['EUR', 'CHF']
amountInfo = 50000
payload = payload.replace('#currencyFrom', currencyFrom).replace('#currencyTo', currencyTo).replace('#amountInfo', amountInfo)
for currFrom in currencyFrom:
for currTo in currencyTo:
for amount in amountInfo:
payload = payload.replace('#currencyFrom', currFrom ).replace('#currencyTo', currTo ).replace('#amountInfo', amount )
response = requests.request("POST", url, data=payload, headers=headers)
Hope this makes sense!
Edit: Updating code as per your comments.
I have a string like this below
data = '[{"cId": "y02", "name": "Test 02", "description": "My Test"}]'
I am sending this data in a http request like
import requests
headers = {
'Content-Type': 'application/json',
}
response = requests.post('http://localhost:8000/targets', headers=headers,data=data, auth=('user', 'pass'))
Now what i would like to do is e.g. i have a string in a variable like..
id=str('random string')
and i would like to add it in data like this..
data = '[{"cId": id, "name": "Test 02", "description": "My Test"}]'
But i am not able to add it. I have tried to first convert the entry in json and then adding it into the array. But server sends the exception back. How can i do that?
You could convert it to a list of dicts.Then convert it to str.(With json module):
import json
data_before = '[{"cId": "y02", "name": "Test 02", "description": "My Test"}]'
tmp = json.loads(data_before)
tmp[0]["cId"] = str('random string')
data_after = json.dumps(tmp)
Then use data_after it like before:
import requests
headers = {
'Content-Type': 'application/json',
}
response = requests.post('http://localhost:8000/targets', headers=headers, data=data_after, auth=('user', 'pass'))
Or pass it as json parameter directly in requests.post:
import json
data_before = '[{"cId": "y02", "name": "Test 02", "description": "My Test"}]'
data_after = json.loads(data_before)
data_after[0]["cId"] = str('random string')
Then do:
import requests
headers = {
'Content-Type': 'application/json',
}
response = requests.post('http://localhost:8000/targets', headers=headers, json=data_after, auth=('user', 'pass'))
data in request.post() should be a :
Dictionary, list of tuples, bytes, or file-like object to send in the body of the :class:Request.
If your data is json formatted, you can load the data and convert the string into a dict using json.load("<str in json format>").
I'm making a request:
import request in python:
url = "http://myweb.com/call"
payload = {}
headers = { 'Content-Type': 'application/json', 'Token': '123456789' }
response = requests.request("POST", url, headers=headers, data = payload)
print(response.text.encode('utf8'))
and I'm receiving and printing the response as :
{"name":"Peter","LastName":JOHN,"RegDate":"2020-03-25T17:34:42.5306823Z","Number":7755}
but I want the print statement to show only "Name" and "Number" params. Not the whole response should be printed. How do I do this?
Thanks in advance.
Response is a dictionary object, so you want to print two values from that dictionary using the keys for those values:
response_text = response.text.encode('utf8')
print(response_text['name'], response_text['Number'])
edit: the dict is actually deeper within the response object than I originally understood.
You can do this:
import json
response = requests.request("POST", url, headers=headers, data = payload)
response_txt=json.loads(response.text.encode('utf8'))
print(response_txt['name'])
print(response_txt['Number'])
response.text.encode('utf8') produces a string, so you need import the json library and convert that string to an object with json.loads. Then you can access the keys with response_txt['name'] and response_txt['Number'].
I'm trying to deploy my production ready code to Heroku to test it. Unfortunately, it is not taking JSON data so we converted into x-www-form-urlencoded.
params = urllib.parse.quote_plus(json.dumps({
'grant_type': 'X',
'username': 'Y',
'password': 'Z'
}))
r = requests.post(URL, data=params)
print(params)
It is showing an error in this line as I guess data=params is not in proper format.
Is there any way to POST the urlencoded parameters to an API?
You don't need to explicitly encode it, simply pass your dict to data argument and it will be encoded automatically.
>>> r = requests.post(URL, data = {'key':'value'})
From the official documentation:
Typically, you want to send some form-encoded data — much like an HTML
form. To do this, simply pass a dictionary to the data argument. Your
dictionary of data will automatically be form-encoded when the request
is made
Set the Content-Type header to application/x-www-form-urlencoded.
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
r = requests.post(URL, data=params, headers=headers)
Just to an important thing to note is that for nested json data you will need to convert the nested json object to string.
data = { 'key1': 'value',
'key2': {
'nested_key1': 'nested_value1',
'nested_key2': 123
}
}
The dictionary needs to be transformed in this format
inner_dictionary = {
'nested_key1': 'nested_value1',
'nested_key2': 123
}
data = { 'key1': 'value',
'key2': json.dumps(inner_dictionary)
}
r = requests.post(URL, data = data)
In Python 3.4 I'm using Requests and a for loop to combine the body for a multiple item API request fetching JSON content. It yields a HTTP 400 error even if the body variable is recognized as a str class with type(). However if I print and copy the content into a new variable it is successful. What kind of formatting is going on?
import requests,json
list_length = len(namelist) #namelist arranged earlier in code
payload='['
for x in range(0, list_length):
payload += '{"name": "'+ namelist[x] + '"}'
if x<list_length-1:
payload += ', '
payload += ']'
url = 'http://api.turfgame.com/v4/users'
headers = {'Content-Type': 'application/json'}
req = requests.post(url, data=json.dumps(payload),headers=headers)
>>> payload
'[{"name": "sune"}, {"name": "Demon"}, {"name": "kingenin"}]'
You are creating a JSON string, then encode it as a JSON string. This double encoding is not what you'll want here:
>>> payload = '[{"name": "sune"}, {"name": "Demon"}, {"name": "kingenin"}]'
>>> print(json.dumps(payload))
"[{\"name\": \"sune\"}, {\"name\": \"Demon\"}, {\"name\": \"kingenin\"}]"
That's a JSON string, containing a quoted JSON list..
Build a list, and pass that to json.dumps():
payload = [{'name': name} for name in namelist]
url = 'http://api.turfgame.com/v4/users'
headers = {'Content-Type': 'application/json'}
req = requests.post(url, data=json.dumps(payload),headers=headers)
This sends a proper JSON list instead:
>>> payload
[{'name': 'sune'}, {'name': 'Demon'}, {'name': 'kingenin'}]
>>> print(json.dumps(payload))
[{"name": "sune"}, {"name": "Demon"}, {"name": "kingenin"}]
You could also send payload as you built it, without passing it to json.dumps(), but why have a dog and bark yourself at all?
If you were to use requests version 2.4.2 or up, you can have it handle the JSON encoding for you; pass in the Python object into the json keyword argument and it'll even set the correct Content-Type header:
payload = [{'name': name} for name in namelist]
url = 'http://api.turfgame.com/v4/users'
req = requests.post(url, json=payload)