Can you get a more comprehensive http response using python requests? - python

I tried calling an API using both python and nodejs but the format in which the response is in is quite different.
For nodejs, it returns the statuscode, headers, body, request etc.
E.g.
(Only an example, not the actual response so you can ignore any syntax errors)
{
"statusCode" : 200,
"headers" : {
'xxxx' : 'xxxx"
},
"body" : {
"name" : "james",
"age" : 35
},
"request" {
"method" : "POST"
}
}
For python, it only returns the response body.
E.g.
(Only an example, not the actual response so you can ignore any syntax errors)
{
'name' : james,
'age' : 35
}
I am aware that i am able to get the headers etc using python request response object such as response.headers etc but is there a way that allows me to a similar response like nodejs. I know about response.dir but i need to forward this response so the format of response.dir is not accepted.
Thanks all!

You can compile your own response, similar to what you get from nodejs, something like
import json
import requests
url = 'http://date.jsontest.com/'
r = requests.get(url)
j = {
"statusCode": r.status_code,
"headers": dict(r.headers),
"body": r.json(),
"request": {
"method": r.request.method
}
}
print(json.dumps(j, indent=4))
Will produce:
{
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
"X-Cloud-Trace-Context": "9b4e313aa5e6373ddc997dc963ee8f1b",
"Date": "Thu, 23 Jun 2022 03:11:27 GMT",
"Server": "Google Frontend",
"Content-Length": "100"
},
"body": {
"date": "06-23-2022",
"milliseconds_since_epoch": 1655953887719,
"time": "03:11:27 AM"
},
"request": {
"method": "GET"
}
}

Related

How to request GET method in specific url using Postman?

I want to get some results using Postman.
expected result :
{
"status": "200",
"message": "success",
"results": {
"count": "6816",
"data": [
{
"timestamp": "2022-07-17T10:47:03Z",
"sender": "0x2F664960a7FBdaDA8e133DbAF1Bfc27DCCBADBfb",
"receiver": "0xA68A135Ccd37E720000fC30CFcc453b15F8040df",
"value": "0",
"status": "1",
"message": "",
"transaction_hash": "0x1a03528eecf165678d7fbcb9ceeee45a98b02f10a5ce30236ef29ee5b3747c84",
"block_number": "2472",
"contract_address": null,
"trace_address": [
"0",
"1",
"1"
],
"trace_type": "staticcall",
"sub_traces": null,
"transaction_index": "0",
"gas_used": "2715",
"gas_limit": "29039032",
"external_receiver": "0",
"input": "0x0d2020dd476f7665726e616e6365436f6e74726163740000000000000000000000000000"
},
...
]
}
}
When I request GET Method for example,
API Docs : https://docs.wemix.com/v/en/dapp-developer/api-reference/account-apis#get-internal-transactions-by-address-and-get-internal-transactions-by-transaction-hash
GET https://explorerapi.test.wemix.com/v1/accounts/0xA68A135Ccd37E720000fC30CFcc453b15F8040df/internal-transactions
api-key: 1ba5e446edf1997f67b51bf9e60b3fbba6fa1bf84301115292805d7e24f43539RESPONSE DATA
I requests GET method using 'api-key' using Postman
but, my response is,
{
"status": "401",
"message": "Unauthorized"
}
How to fix it to get proper response?
Or, is there a good way to call API with Python?
In addition to Khalil's answer - to do the same in python you could do the following:
import requests
headers = {'api-key': '1ba5e446edf1997f67b51bf9e60b3fbba6fa1bf84301115292805d7e24f43539'}
response = requests.get('https://explorerapi.test.wemix.com/v1/accounts/0xA68A135Ccd37E720000fC30CFcc453b15F8040df/internal-transactions', headers=headers)
print(response)
<Response [200]> which will get you the data that you desire.
The API Key that was provided had RESPONSE DATA at the end which was invalid as the API key.
On the Headers tab, you need to add a key api-key with the api key 1ba5e446edf1997f67b51bf9e60b3fbba6fa1bf84301115292805d7e24f43539 in the value.

API FedEX "INVALID.INPUT.EXCEPTION","message":"Invalid field value in the input"

I'm trying to validade an address in FedEX API using Python 3.8 and it returns an error of invalid field value
First I connect to the Auth API
payload={"grant_type": "client_credentials",'client_id':Client_id,'client_secret':Client_secret}
url = "https://apis-sandbox.fedex.com/oauth/token"
headers = {'Content-Type': "application/x-www-form-urlencoded"}
response=requests.post(url, data=(payload), headers=headers)
And it returns a message with the Auth token correctly
{"access_token":"eyJhbGciOiJSUzI1NiIsInRM5U0F2eUs1ZVFBVTFzS5k","token_type":"bearer","expires_in":3599,"scope":"CXS SECURE"}
Then I just get the token to use it in next transactions
token = json.loads(response.text)['access_token']
Then I prepare the next payload for address validation API
payload_valid_address = {
"addressesToValidate": [
{
"address":
{
"streetLines": ["7372 PARKRIDGE BLVD"],
"city": "Irving",
"stateOrProvinceCode": "TX",
"postalCode": "75063-8659",
"countryCode": "US"
}
}
]
}
And send the request to the new endpoint with the given token
url = "https://apis-sandbox.fedex.com/address/v1/addresses/resolve"
headers = {
'Content-Type': "application/json",
'X-locale': "en_US",
'Authorization': 'Bearer '+ token
}
response = requests.post(url, data=payload_valid_address, headers=headers)
print(response.text)
and get the error
<Response [422]>
{"transactionId":"50eae03e-0fec-4ec7-b068-d5c456b64fe5","errors":[{"code":"INVALID.INPUT.EXCEPTION","message":"Invalid field value in the input"}]}
I have made inumerous tests and I don't get the invalid field.
Anyone know what is happening and can help?
payload = json.dumps({input payload}) this works to prevent the response error 422
<Response [422]>
I have fixed it
For any reason, convert the string payload_valid_address to Json in 2 steps doesn't work
payload_valid_address = {....}
payload = json.dumps(payload_valid_address)
But if made in just one step it pass the API request
payload_valid_address = json.dumps({....})
I also had this error and additionally had to use json.loads(json_string) when the json data contained key words like false, true or null.
import json
json_string = r'''{
"accountNumber": {
"value": "802255209"
},
"requestedShipment": {
"shipper": {
"address": {
"postalCode": 75063,
"countryCode": "US"
}
},
"recipient": {
"address": {
"postalCode": "m1m1m1",
"countryCode": "CA"
}
},
"shipDateStamp": "2020-07-03",
"pickupType": "DROPOFF_AT_FEDEX_LOCATION",
"serviceType": "INTERNATIONAL_PRIORITY",
"rateRequestType": [
"LIST",
"ACCOUNT"
],
"customsClearanceDetail": {
"dutiesPayment": {
"paymentType": "SENDER",
"payor": {
"responsibleParty": null
}
},
"commodities": [
{
"description": "Camera",
"quantity": 1,
"quantityUnits": "PCS",
"weight": {
"units": "KG",
"value": 20
},
"customsValue": {
"amount": 100,
"currency": "USD"
}
}
]
},
"requestedPackageLineItems": [
{
"weight": {
"units": "KG",
"value": 20
}
}
]
}
}'''
data = json.loads(json_string)
data
response = requests.request("POST", url, data=json.dumps(data), headers=headers)
I have managed to get Fedex to accept my ayload, however i get this message:
"code":"INVALID.INPUT.EXCEPTION","message":"Validation failed for object='shipShipmentInputVO'. Error count: 1","parameterList":[{"key":"NotNull.shipShipmentInputVO.labelResponseOptions","value":"labelResponseOptions cannot be null"
and when I add the required parameter
'labelResponseOptions': "URL_ONLY"
I get this:
"code":"SYSTEM.UNEXPECTED.ERROR","message":"The system has experienced an unexpected problem and is unable to complete your request. Please try again later. We regret any inconvenience."
Is this really some Fedex internal error?

Python POST request with Nested Dictionary values/args

Already looked at here, here and here but still having issues.
I have a POST data that looks like this:
{
"config":{
"param1": "param1 value",
"param2": "param2 value",
"param3": "param3 value"
},
"name": "Testing API",
"url": "https://testingapi.my.own.com",
"enabled": true
}
I have the following headers:
{
"Content-Type": "application/json",
"referer": "https://testingapi.my.own.com",
"X-CSRFToken": "my token value here"
}
How do format this for the session.post?
I am keep getting the response code of 400 and logs are stating that I am not sending the required params in the post request.
Here is the code:
headers = {"Content-Type": "application/json",
"referer": "https://testingapi.my.own.com",
"X-CSRFToken": "my token"
}
request_data = {
"config":{
"param1": "param1 value",
"param2": "param2 value",
"param3": "param3 value"
},
"name": "Testing API",
"url": "https://testingapi.my.own.com",
"enabled": "true"
}
#tried the following:
r = session.post(url, data = request_data, headers=headers)
r = session.post(url, json = json.dumps(request_data), headers=headers)
When you do data = request_data your nested dictionary is not packaged into the request body as you expect. Try inspecting the body attribute of the request object:
import requests
s = requests.Session()
request_data = {
"config":{
"param1": "param1 value",
"param2": "param2 value",
"param3": "param3 value"
},
"name": "Testing API",
"url": "https://testingapi.my.own.com",
"enabled": True
}
r = s.post('https://httpbin.org/post/404', data=request_data )
r.request.body
returns
'url=https%3A%2F%2Ftestingapi.my.own.com&enabled=True&config=param3&config=param2&config=param1&name=Testing+API'
And when you json = json.dumps(request_data) you json-dump your data twice, so so the server (after unserializing the data one time) only sees a json string rather than an unserialized dict (see requests docs).
So you need to either serialize your data before passing it to data
r = s.post('https://httpbin.org/post/404', data=json.dumps(request_data), )
or as Paul has suggested, use the json parameter and pass your data dict to it:
r = s.post('https://httpbin.org/post/404', json=request_data)

Print status code from the post in a json-rpc call

I have a working script that does the job just fine but I can't seem to figure out how to print the status code after the script runs.
Can someone please review and provide some guidance and help?
import requests
import json
url = 'http://10.3.198.100/ins'
switchuser = 'user'
switchpassword = 'password'
myheaders = {'content-type' : 'application/json-rpc'}
payload = [
{
"jsonrpc": "2.0",
"method": "cli",
"params": {
"cmd": "vrf context management",
"version": 1
},
"id": 1
},
{
"jsonrpc": "2.0",
"method": "cli",
"params": {
"cmd": "ip route 192.168.255.0/24 10.3.198.130",
"version": 1
},
"id": 2
},
{
"jsonrpc": "2.0",
"method": "cli",
"params": {
"cmd": "copy run start",
"version": 1
},
"id": 3
}
]
response = requests.post(url, data = json.dumps(payload), headers = myheaders, auth = (switchuser, switchpassword)).json()
You are immediately calling .json() after your .post() returns. This means that you are throwing away the rest of the info from the response.
Try this instead:
response = requests.post(
url,data=json.dumps(payload),
headers=myheaders,
auth=(switchuser,switchpassword))
json_response = response.json()
print(response.status_code)
Reference: http://docs.python-requests.org/

Paypal Rest API keeps returning malformed json error

I am trying to create payment using paypal Rest API, but I keep getting this error response:
{"name":"MALFORMED_REQUEST","message":"The request JSON is not well formed.","information_link":"https://developer.paypal.com/webapps/developer/docs/api/#MALFORMED_REQUEST","debug_id":"262cbdc417df7"}
here with my code:
payment_url = 'https://api.sandbox.paypal.com/v1/payments/payment'
headers = {"Content-Type": "application/json", "Authorization": "Bearer %s" % access_token}
data = {
"intent": "sale",
"redirect_urls": {
"return_url": "http://localhost:8080/index.html",
"cancel_url": "http://localhost:8080/index.html"
},
"payer": {
"payment_method": "paypal"
},
"transactions": [
{
"amount": {
"total": "7.47",
"currency": "USD"
},
"details": {
"subtotal": "7.41",
"tax": "0.03",
"shipping": "0.03"
},
"description": "This is the payment transaction description.",
"item_list": {
"items": [
{
"quantity": "1",
"name": "item",
"price": "7.41",
"currency": "USD",
"sku": "item"
}]
}
}
]
}
print headers
print data
r = requests.post(payment_url, headers=headers, data=data)
print 'payment res', r.text
And I only get the response like this:
{"name":"MALFORMED_REQUEST","message":"The request JSON is not well formed.","information_link":"https://developer.paypal.com/webapps/developer/docs/api/#MALFORMED_REQUEST","debug_id":"262cbdc417df7"}
I have seen quite a few questions regarding this kind of error, but none of them have solution yet. :(
The json formated post data is obviously valid. Otherwise, requests post method would raise exceptions. And the response is returned from paypal server, but I can't find any information from the link it gave. I have checked Rest API documentation, and I think I made the request exactly as the samples. What did I miss?
Any kind advice or solution would be appreciated.
Your return_url and cancel_url values need to have quotes around them. As the message says, your JSON is malformed.
Try this - http://jsonlint.com/ to see your errors.

Categories