python3 -- getting POST request text from requests.post? - python-3.x

I'm using python3. For debugging purposes, I'd like to get the exact text that is sent to the remote server via a requests.post command. The requests.post object seems to contain the response text, but I'm looking for the request text.
For example ...
import requests
import json
headers = {'User-Agent': 'Mozilla/5.0'}
payload = json.dumps({'abc':'def','ghi':'jkl'})
url = 'http://example.com/site.php'
r = requests.post(url, headers=headers, data=payload)
How do I get the text of the exact request that is sent to url via this POST command?

Related

Urllib3 POST request with attachment in python

I wish to make a post request to add an attachment utilising urllib3 in python without success. I have confirmed the API itself is working in postman but cannot work out how to convert this request to python. Appreciating I'm mixing object types I just don't know how to avoid it.
Python code:
import urllib3
import json
api_key = "secret_key"
header = {"X-API-KEY": api_key, "ACCEPT": "application/json", "content-type": "multipart/form-data"}
url = "https://secret_url.com/api/"
http = urllib3.PoolManager()
with open("invoice.html", 'rb') as f:
file_data = f.read()
payload = {
"attchment": {
"file": file_data
}
}
payload = json.dumps(payload)
r = http.request('post', url, headers = header, fields = payload)
print(r.status)
print(r.data)
Postman - which works and properly sends file-name through also (I'm guessing it splits the bytes and filename up?)
Edit: I've also tried the requests library as I'm more familiar with this (but can't use it as the script will be running in AWS lambda). Removing the attachment element form the dict allows it to run but the API endpoint gives 401 presumably because it's missing the "attachement" part to the data structure as per postman below... but when I put this in I get runtime errors.
r = requests.post(url, headers = header, files={"file": open("invoice.html", 'rb')})
For anyone who stumbles upon this from Dr google a few points:
I was completely mis-interpreting the structure of the element. It's actually a string "attachment[file]" not a dict like object.
Postman has the ability to output python code in urllib/request syntax albeit not 100% what I was after. Note: the chrome version (depreciated) outputs gibberish code that only half works so the client version should be used. A short bit of work below shows it working as expected:
http = urllib3.PoolManager()
with open("invoice.html", "rb") as f:
file = f.read()
payload={
'attachment[file]':('invoice.html',file,'text/html')
}
r = http.request('post', url, headers = header, fields = payload)

Can't send proper post request with file using python3 requests

I was using Postman to send post request like on the screenshot
Now I need to implement it in python. This is what i've got for now:
import requests
data = {"sendRequest": {"apiKey": 12345, "field1": "field1value"}}
files = {"attachment": ("file.txt", open("file.txt", "rb"))}
headers = {"Content-type": "multipart/form-data"}
response = requests.post(endpoint, data=data, headers=headers, files=files)
But still it's not working - server doesn't accept it as valid request. I've tried more combinations but without any results and I really couldn't find a solution.
I need this request to be exactly like that one in postman
I finally found a solution. I used MultipartEncoder from requests_toolbelt library.
from requests_toolbelt import MultipartEncoder
import requests
import json
data = {"apiKey": 12345, "field1": "field1value"}}
mp = MultipartEncoder(
fields={
'sendRequest': json.dumps(data), # it is important to convert dict into json
'attachment': ('file.pdf', open('file.pdf', 'rb'), 'multipart/form-data'),
}
)
r = requests.post(ENDPOINT, data=mp, headers={'Content-Type': mp.content_type})

How to get a POST request using python on HERE route matching API?

I've tried to do a POST request using python's request library, which looked something like below:
url = "https://rme.api.here.com/2/matchroute.json?routemode=car&filetype=CSV&app_id={id}&app_code={code}"
response = requests.post(url,data='Datasets/rtHereTest.csv')
The response I've been getting a code 400
{'faultCode': '16a6f70f-1fa3-4b57-9ef3-a0a440f8a42e',
'responseCode': '400 Bad Request',
'message': 'Column LATITUDE missing'}
However, in my dataset, here I have all the headings that's required from the HERE API documentation to be able to make a call.
Is there something I'm doing wrong, I don't quite understand the POST call or the requirement as the HERE documentation doesn't explicitly give many examples.
The data field of your post request should contain the actual data, not just a filename. Try loading the file first:
f = open('Datasets/rtHereTest.csv', 'r')
url = "https://rme.api.here.com/2/matchroute.json?routemode=car&filetype=CSV&app_id={id}&app_code={code}"
response = requests.post(url, data=f.read())
f.close()
Here's what I use in my own code, with the coordinates defined before:
query = 'https://rme.api.here.com/2/matchroute.json?routemode=car&app_id={id}&app_code={code}'.format(id=app_id, code=app_code)
coord_strings = ['{:.5f},{:.5f}'.format(coord[0], coord[1]) for coord in coords]
data = 'latitude,longitude\n' + '\n'.join(coord_strings)
result = requests.post(query, data=data)
You can try to post the data using below format.
import requests
url = "https://rme.api.here.com/2/matchroute.json"
querystring = {"routemode":"car","app_id":"{app_id}","app_code":"{app_code}","filetype":"CSV"}
data=open('path of CSV file','r')
headers = {'Content-Type': "Content-Type: text/csv;charset=utf-8",
'Accept-Encoding': "gzip, deflate",
}
response = requests.request("POST", url, data=data.read().encode('utf-8'), params=querystring,headers=headers)
print(response.status_code)

MissingSchema - Invalid URL Error with Requests module

Trying to get data from the eBay API using GetItem. But requests isn't reading or getting the URL properly, any ideas? Getting this error:
requests.exceptions.MissingSchema: Invalid URL '<urllib.request.Request object at 0x00E86210>': No schema supplied. Perhaps you meant http://<urllib.request.Request object at 0x00E86210>?
I swear I had this code working before but now it's not, so I'm not sure why.
My code:
from urllib import request as urllib
import requests
url = 'https://api.ebay.com/ws/api.dll'
data = '''<?xml version="1.0" encoding="utf-8"?>
<GetItemRequest xmlns="urn:ebay:apis:eBLBaseComponents">
<RequesterCredentials>
<eBayAuthToken>my-auth-token</eBayAuthToken>
</RequesterCredentials>
<ItemID>any-item-id</ItemID>
</GetItemRequest>'''
headers = {
'Content-Type' : 'text/xml',
'X-EBAY-API-COMPATIBILITY-LEVEL' : 719,
'X-EBAY-API-DEV-NAME' : 'dev-name',
'X-EBAY-API-APP-NAME' : 'app-name',
'X-EBAY-API-CERT-NAME' : 'cert-name',
'X-EBAY-API-SITEID' : 3,
'X-EBAY-API-CALL-NAME' : 'GetItem',
}
req = urllib.Request(url, data, headers)
resp = requests.get(req)
content = resp.read()
print(content)
Thank you in advance. Any good reading material for urllib would be great, too.
You are mixing the urllib and the requests library. They are different libraries that can both do HTTP-requests in Python. I'd suggest you use only the requests library.
Remove the line req = urllib.Request(url, data, headers) and replace the resp = ... line with:
r = requests.post(url, data=data, headers=headers)
Print the response body like this:
print(r.text)
Check out the Requests Quickstart here for more examples: https://2.python-requests.org//en/master/user/quickstart/

Sending cookies with python request

I'm trying to make a post request with python's requests module.
I'm passing the headers, cookies, and data as part of the post request.
When I make the request,I get 400 bad request in the output.
I verified the payload and it looks correct to me. I'm wondering If my syntax for cookie is correct.
#!/usr/local/bin/python
import requests
session = "ASDFGHTR/=FGHYTYKSDMN="
lastmanaged = "9ycG9yYXRpb25fRGlyZWN0I"
header = {'akm-accept':'akm/cookie'}
cookie = {'SESSION': session,
'LASTMANAGED':lastmanaged}
data = {'client': '0ad3cfb66-4fa0-b94a-1bf712eae628&grant_type=password_assertion'}
url = "https://hostname-goes-here"
session = requests.Session()
response = session.post(url, headers=header, cookies=cookie, data=data,
verify=False, allow_redirects=False)
print(response.text)
print(response.status_code)
output:
{"code":"invalid_request","title":"One or more fields in request are invalid","incidentId":"f1fbba64-17e4-4d88-852f-01c137fa012e","requestId":"-5011561246754340090","solution":"none"}
400

Resources