I'm working on a project using Python(3.7) in which I have to parse a JSON returned from the POST request using Requests library.
I googled a lot and tried too many solutions but nothing helped me, so
don't mark this as duplicate, please!
Here's what I have tried:
def process_req(payload):
try:
headers = {
'Content-Type': 'application/json'
}
data = payload
resp = requests.post(
'http://<EXAMPLE_URL>',
data=data,
headers=headers
)
print('returned data: {}'.format(resp.content.decode('utf8').replace("'", '"')))
resp = resp.content.decode('utf8').replace("'", '"')
When I print the resp it provide the following JSON:
{
"code": "00",
"message": "Successful",
"data": "{\"requestId\":\"0012602\",\"responseCode\":\"68\",\"responseDescription\":\"Invalid Institution Code\"}"
}
Now, I need to access the data field of that JSON, here what I tried:
resp['data']
But it returns an error as:
string indices must be integers
You're retrieving the data as raw bytes by using resp.content.
Try resp.json() instead. This will decode the JSON into Python objects.
Related
When I run a Post Statement with a query in the body on the Postman Application it looks like this and works great:
Postman
I am trying to do the same thing with Python using the request library. Here is my code so far:
import requests
query ={
"dataset": "keywordgroup",
"dimension": ["time", "domain", "domain:id","keywordgroup"],
"dimensionOptions": {"time": "weekly"},
"filter": [["time", "eq", "202101"], ["keywordgroup:id", ["-1"]],
["search_engine", [["1", "34"]]]],
"measures": ["pos_band_2","blended_pos_band_2"],
"count":1000,
"offset":0
}
headers = {"Content-Type": 'application/json'}
response = requests.post("https://api.brightedge.com/3.0/query/123456", auth('myemail#gmail.com','mypassword'), headers = headers, data= query)
print(response.text)
output:
{"error": {"errorcode": 0, "errormsg": "Missing POST 'query' parameter"}}
I am not sure why it isn't picking up on the query parameter. Does the query not go in the data parameter of the Post Statement? Do I need to format the query variable differently?
Figured it out, just made the whole statement a string. Then just said 'data = body' instead of 'data = query':
body = "query={\"dataset\": \"keywordgroup\",\"dimension\": [\"time\", \"domain\", \"domain:id\",\"keywordgroup\"],\"dimensionOptions\": {\"time\": \"weekly\"},\"filter\": [[\"time\", \"eq\", \"202101\"], [\"keywordgroup:id\", [\"-1\"]],[\"search_engine\", [[\"1\", \"34\"]]]],\"measures\": [\"pos_band_2\",\"blended_pos_band_2\"],\"count\":1000,\"offset\":0}"
The parameter was looking for a string as opposed to a variable.
I'm trying to POST data to an api, after execution the compiler does not give any errors, but the data is not showing in the database.
import requests
endpoint = "http://192.168.10.2:8085/api/customer"
myObj = {"customer_id": 900,
"customer_code": "qwertyuiop",
"ustomer_name": "lion",
"contact": "030190000",
"address": "lane"}
x = requests.post(url = endpoint, data = myObj)
Edit:
when I try to do
print(x.text)
I get this error:
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.13","title":"Unsupported Media Type","status":415,"traceId":"00-9b47b6c7ce1f14499652ba95b3faca3a-cc8e04f53a002647-00"}
Any help would be appreciated.
I found the problem, I needed to use json (which takes a dictionary) instead of data (which takes a string).
import json
import requests
payload = {"customer_id": 456, "customer_code": "fakhr", "customer_name": "fakhr", "contact": "fakhr", "address": "fakhr"}
r = requests.post("http://192.168.10.2:8085/api/customer", json=payload)
print(r.text)
I am sending an http request to a server, and it keeps throwing a 400 http error
with an error message of Non Canonical Serialization. I am trying to get my head around what this message means from what i've read up so far it sounds like it has something to do with my object keys not being sorted when I serialize it to JSON meaning the server doesn't get the same result each time I send the request I just wanted to know if this is along the right lines? Or is it something else totally?
Here is my code sending the request to the server:
def submit(mutation, pubkey, signature):
headers = {'content-type' : 'application/json'}
url = "http://192.168.99.100:8080/submit/"
data = {
"mutation": mutation,
"signatures": [
{
"pub_key": pubkey,
"signature": signature
}
]
}
response = urllib2.Request(url, headers = { "Content-Type": "application/json"}, data=json.dumps(data))
f = urllib2.urlopen(response)
print f
I've been trying to make a request to an API, I have to pass the following body:
{
"description":"Tenaris",
"ticker":"TS.BA",
"industry":"Metalúrgica",
"currency":"ARS"
}
Altough the code seems to be right and it finished with "Process finished with exit code 0", it's not working well. I have no idea of what I'm missing but this is my code:
http = urllib3.PoolManager()
http.urlopen('POST', 'http://localhost:8080/assets', headers={'Content-Type':'application/json'},
data={
"description":"Tenaris",
"ticker":"TS.BA",
"industry":"Metalúrgica",
"currency":"ARS"
})
By the way, this the first day working with Python so excuse me if I'm not specific enough.
Since you're trying to pass in a JSON request, you'll need to encode the body as JSON and pass it in with the body field.
For your example, you want to do something like:
import json
encoded_body = json.dumps({
"description": "Tenaris",
"ticker": "TS.BA",
"industry": "Metalúrgica",
"currency": "ARS",
})
http = urllib3.PoolManager()
r = http.request('POST', 'http://localhost:8080/assets',
headers={'Content-Type': 'application/json'},
body=encoded_body)
print r.read() # Do something with the response?
Edit: My original answer was wrong. Updated it to encode the JSON. Also, related question: How do I pass raw POST data into urllib3?
I ran into this issue when making a call to Gitlab CI. Since the above did not work for me (gave me some kind of error about not being able to concatenate bytes to a string), and because the arguments I was attempting to pass were nested, I thought I would post what ended up working for me:
API_ENDPOINT = "https://gitlab.com/api/v4/projects/{}/pipeline".format(GITLAB_PROJECT_ID)
API_TOKEN = "SomeToken"
data = {
"ref": ref,
"variables": [
{
"key": "ENVIRONMENT",
"value": some_env
},
{ "key": "S3BUCKET",
"value": some_bucket
},
]
}
req_headers = {
'Content-Type': 'application/json',
'PRIVATE-TOKEN': API_TOKEN,
}
http = urllib3.PoolManager()
encoded_data = json.dumps(data).encode('utf-8')
r = http.request('POST', API_ENDPOINT,
headers=req_headers,
body=encoded_data)
resp_body = r.data.decode('utf-8')
resp_dict = json.loads(r.data.decode('utf-8'))
logger.info('Response Code: {}'.format(r.status))
logger.info('Response Body: {}'.format(resp_body))
if 'message' in resp_body:
logfile_msg = 'Failed Gitlab Response-- {} {message}'.format(r.status, **resp_dict)
I recently became interested in using urllib3, and came across this problem. If you read the urllib3 "User Guide" page, you will see this:
For POST and PUT requests, you need to manually encode query parameters in the URL
Your code should be adjusted to look like this:
import urllib3
from urllib.parse import urlencode
data = {"description":"Tenaris",
"ticker":"TS.BA",
"industry":"Metalúrgica",
"currency":"ARS"}
http = urllib3.PoolManager()
encoded_data = urlencode(data)
http.request('POST',
'http://localhost:8080/assets?'+encoded_data,
headers={'Content-Type':'application/json'})
I have the necessary authentication details and I'm trying to do a TransactionSearch. I keep getting an error:
ACK=Failure&L_ERRORCODE0=81002&L_SHORTMESSAGE0=Unspecified%20Method&L_LONGMESSAGE0=Method%20Specified%20is%20not%20Supported&L_SEVERITYCODE0=Error
Here is my code:
(timestamp, signature) = signaturegen.getAuthHeader(apiUser=settings.USERNAME, apiPass=settings.PASSWORD, accessTok=res2["token"], secTok=res2["tokenSecret"], httpMethod="POST", scriptURI="https://api-3t.sandbox.paypal.com/nvp")
#the above operation is used to generate the timestamp and signature
headers = {"X-PAYPAL-AUTHORIZATION": "timestamp="+<timestamp>+",token="+<token>+",signature="+<signature>, "SUBJECT": settings.<API_USERNAME>}
data = {
"METHOD": "TransactionSearch",
"STARTDATE": "2012-01-01T05:38:48Z",
}
req= urllib2.Request("https://api-3t.sandbox.paypal.com/nvp", simplejson.dumps(data), headers)
res = urllib2.urlopen(req).read()
What i'm I doing wrong.
Use urllib.urlencode instead of simplejson.dumps for merchant nvp APIs.
req= urllib2.Request("https://api-3t.sandbox.paypal.com/nvp", urllib.urlencode(data), headers)