I am trying to issue a POST request including local-file upload with python.
I looked up a lot of similar requests here, but none worked for me or none was specific enough to help me out.
With Postman everything works as expected and without any hickups.
But representing the very same with python I am not able to achieve it.
I tried various combinations of params-, body- and file-dictionaries, without success
This is how the working postman request body looks like:
This is how the params of this postman request have been configured:
This is my python code
metadata = {
"name":"MyFile" ,
"type":"myFileType" ,
"parentId":"1cc58622-3bc0-4fc4-a222-a64bd8d90af1"
}
fileForUpload = {'upload_file': open("/home/myuser/blablabla/testfile.jpg)", "rb")}
params = {"metadata":json.dumps(metadata), "file": "filename"}
headers = {
"content-type": "application/json",
"Authorization": 'Bearer ' + token,
"accept-encoding": "gzip, deflate"
}
response = requests.post(url, headers = headers, params = params, files = fileForUpload)
I receive an error message of the API-endpoint, claiming that the file parameter is missing ...
Any idea what I am doing wrong?
Related
I am struggling to delete an attachable using the Quickbooks API.
I keep getting the error: ""Message":"Error parsing object","Detail":"ObjectParserError: Request Body is Empty","code":"2310","element":""
I wrote the following function (I put hard coded values to make sure that it works properly). The accessToken is definitely accurate as it works properly for other functions.
def deleteAttachable(accessToken):
base_url = 'https://sandbox-quickbooks.api.intuit.com/'
url = '{0}/v3/company/{1}/attachable?operation=delete'.format(base_url, cfg.qBData["realm_id"])
auth_header = 'Bearer {0}'.format(accessToken)
headers = {
"SyncToken": "0",
"domain": "QBO",
'Id': "5000000000001149164",
"FileName" : "bf546e8b-1dc4-4e42-b305-6435c28e2d8a1-AMAZON THERMOSTAT.pdf",
'Authorization': auth_header,
'Content-type': 'application/json'
}
print(url)
print(headers)
response = requests.post(url, headers=headers)
I was able to get the auth token from the login api but I am trying to use it to query the events api and I am getting a 401 Client Error: Unauthorized for url error message. Here is a snippet of my code:
def action():
data = {
'login': 'xxxxxxxxx',
'password': 'xxxxx',
}
urllib3.disable_warnings()
try:
timestamp = int(round(time.time() * 1000))
print(timestamp)
r = requests.post(
'https://host:port/www/core-service/rest/LoginService/login', data=data, verify=False)
login_request = untangle.parse(r.text)
user_session_id = login_request.ns3_loginResponse.ns3_return.cdata
print(user_session_id)
response = requests.post(
'https://host:port/detect-api/rest/v1/events/retrieve',
headers={
"Accept": "application/json",
"Authorization": user_session_id,
"Content-Type": "application/json"
},
data={
"ids": 79745681,
"startTime": timestamp,
"endTime": timestamp
},
verify=False)
print(response)
res = untangle.parse(response.text)
print(res)
Can somebody please point out what is wrong with my code?
You didn't add link to API so I only guess what can make problem.
If you set "Content-Type": "application/json" then it can means you want to send json data.
So you should use
post(..., json=...)
instead of
post(..., data=...).
Using data= you send it as form, not json. And header Content-Type can't change it.
And when you use json= then you don't have to add "Content-Type": "application/json" because requests will add it automatically.
EDIT:
In comment you said that you have working curl command (but you didn't said it in question, and you didn't show curl in question)
On page https://curl.trillworks.com you can convert curl to Python (and few other languages) and mostly it works correctly.
BTW:
If you use postman for tests then it has also function to generate code for curl, Python and many other languages.
You didn't show link to API documentation but often API documentation has examples for curl and sometimes even for Python.
I am attempting to run a POST request in python. When I test in Postman it runs fine and imports the file. When I run it in Python I error out. This posts a spreadsheet stored on my computer into Quip. I am getting the error missing argument 'file'. I have tried moving several things around and am not sure what im missing. here is what im working with:
import requests
url = "https://platform.quip.com/1/threads/import-file"
payload = {'type': 'spreadsheet'}
files = [
('file', open('/Users/admin/Documents/excel/logs/Output/test.xlsx','rb'))
]
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer **************************='
}
response = requests.request("POST", url, headers=headers, data = payload, files = files)
print(response.text.encode('utf8'))
Try to change this line:
files = {'file': open('/Users/admin/Documents/excel/logs/Output/test.xlsx','rb')}
Also I noticed a bug in Postman (version 9.9.1): payload contains only the first field. Be aware of that.
So I would not rely on generated code.
I am trying to insert a destination order using action=insertDestinationOrder
I am using POST method with all required parameters, but keep getting
{
"errorCode": 40,
"errorMsg": "general error"
}
I have checked using postman too. But still same.
Below is the request using python requests package.
import requests
url = "https://csv.telematics.tomtom.com/extern"
payload = "orderid=TO0049&country=DE&city=Cologne&latitude=50974519&ordertype=delivery%20order&zip=50735&longitude=6977319&street=Am%20Niehler%20Hafen%20%26%20Stapelkai%2C%2050735%20Cologne%20(Niehl)&account=XXXX&username=XXXX&password=XXXX&apikey=XXXX&lang=en&action=insertDestinationOrder&ordertext=Am%20Niehler%20Hafen%20%26%20Stapelkai%2C%2050735%20Cologne%20(Niehl)&useUTF8=true&outputformat=json"
headers = {
'content-type': "application/x-www-form-urlencoded"
}
response = requests.request("POST", url, data=payload, headers=headers)
print(response.text)
Need some help.
Try adding a ? to the end of the url, or to the start of the payload:
url = "https://csv.telematics.tomtom.com/extern?"
or
payload = "?orderid=TO0049&country=DE&city=Cologne&latitude=50974519&ordertype=delivery%20order&zip=50735&longitude=6977319&street=Am%20Niehler%20Hafen%20%26%20Stapelkai%2C%2050735%20Cologne%20(Niehl)&account=XXXX&username=XXXX&password=XXXX&apikey=XXXX&lang=en&action=insertDestinationOrder&ordertext=Am%20Niehler%20Hafen%20%26%20Stapelkai%2C%2050735%20Cologne%20(Niehl)&useUTF8=true&outputformat=json"
I have a client id and client secret and am attempting to generate an auth token by following Sitescout's api docs. I'm using python module Requests and am getting a 400 status code back, aka malformed request, but I can't seem to figure out why.
My code:
import requests
url = "https://api.sitescout.com/oauth/token"
headers = {
"Host": "api.sitescout.com",
"Authorization": "Basic YmVldGhvdmVuOmxldG1laW4=",
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json",
"Content-Length": "41"
}
# Do the HTTP request
response = requests.post(url, headers=headers)
response.status_code
That is the fake base64 Authorization header provided in the docs so this snippet returns a 401 error, aka unauthorized (I have my own auth of course).
Can anyone tell me what's wrong with this?
It has been resolved. I did not put grant_type=client_credentials which, when added, returns a 200.
The docs say "Optionally, you can add form parameter scope to indicate which scopes you are requesting access to; the scope values must be space delimited (e.g., STATS AUDIENCES)." But it is the "&scope=STATS" param that is optional, not all params. The example confused me.
Now my code reads
...
params = { "grant_type" : "client_credentials" }
response = requests.post(url, headers=headers, params=params)
...
which works.