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)
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'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 am using python flask framework to send data from server to client via https
Below is the code
#xyz.route('/hello', methods=['GET', 'POST'])
def hello():
message = request.args.get("messagetosend")
datadict = {"sendingData": message}
url = "https://IP:PORT"
certificate = "stack.f1"
keys = "stack.f2"
cert = (certificate , keys )
r = requests.request("POST", url, verify=False, cert=cert, data=datadict)
return "dataPosted"
datadict = {"sendingData": message} : This is because my client machine understands the request in this format only.
But when the datadict type is dict, client is not getting receiving data. But when I change the dict to string like str = "sendingData="+message, client machine is receiving data
Any idea why is this happening like this?
Why not just use requests.post as in the documentation?
>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.post("http://httpbin.org/post", data=payload)
>>> print(r.text)
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}
You should use JSON in this request.
import json
replace data=datadict with data=json.dumps(datadict).
On clientside you can access the JSON file with javascript:
var data_set = jQuery.parseJSON({{ data }});
if you store it in a hidden field, then use:
var data_set = jQuery.parseJSON($('#hidden_field_id').html());
I am trying to make api call which has json as value to one of the keys. It is failing because of extra double quotes in inner json formed.
variable = request.GET.get('name', '{}')
This value of variable is json that is passed from webpage.
Sample data in variable will be like:-
variable= {'name': 'ABC', 'Id': '1'}
Now when I try to form my payload to be sent in post call,
payload = {
'var1': var1,
'variable': variable,
}
Now this "variable" which is added to payload is treated as String and append with double quotes, like this:-
{'var1': '130', 'variable': "{'name': 'ABC', 'Id': '1'}"}
But I want it to be like this:-
{'var1': '130', 'variable': {'name': 'ABC', 'Id': '1'}}
Any suggestions how to make it possible?
this is the code to make the post call with data:-
r = requests.post("URL",data= json.dumps(payload),headers={'Authorization': obj.header, 'Content-type': 'application/json'}, proxies=getProxyDict())
When you get variable from the request it isn't just 'treated' as a string... is is a string.
So you need to:
json.loads(variable)
before adding it to the dict which is later serialized to json.
i.e.
variable = json.loads(request.GET.get('name', '{}'))
payload = {
'var1': var1,
'variable': variable,
}
r = requests.post("URL",data= json.dumps(payload),headers={'Authorization': obj.header, 'Content-type': 'application/json'}, proxies=getProxyDict())
You have presumably already dumped variable to a JSON string. Don't do that; leave it as a dict, and dump the whole thing in one go.
import json
variable = {'name': 'ABC', 'Id': '1'}
payload = {
'var1': 'foo',
'variable': variable,
}
print json.dumps(payload, indent=4)
results to
{
"variable": {
"name": "ABC",
"Id": "1"
},
"var1": "foo"
}
which is perfectly json. But, you may need to set your headers according to the API you're talking to.
request = requests.get('myurl', headers={'accept': 'application/json'})
json_data = request.json()
# manipulate json_data
request = requests.post('myurl', headers={'content-type': 'application/json'}, json=json_data)
Few things I would like to point here.
variable= "{'name': 'ABC', 'Id': '1'}"
This is NOT a valid json string.
variable= '{"name": "ABC", "Id": "1"}'
This is a valid json string.
So first before attaching this variable to payload dict you need to convert it to a python dict like this.
variable = json.loads(variable)
This will create variable something like this.
{u'name': u'ABC', u'Id': u'1'}
Now you can go ahead and add this to your payload dict and continue what you are doing.
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)