Send image in request from python - python

I am trying to upload an image using POST request. From Postman, it is giving success but when I try same code from python, I am getting an error (payload validation failed). Following is my code in python:
import requests
url = "http://10....."
payload = {}
files=[('pdf_file',('passport.jpg', open('/D:/passport.jpg','rb'), 'image/jpeg'))]
headers = {
'accept':'application/json',
'Content-Type':'multipart/form-data',
'Authorization':'<token_here>',
}
response = requests.request("POST", url, headers = headers, data = payload, files = files)
print(response.text)
While invoking request from postman, headers are same as above code. Select form-data in body section and upload image for key "pdf_file".
Is there any difference in both approaches?

You should omit content type from headers
headers = {
'accept':'application/json',
'Authorization':'<token_here>'
}

Related

Upload file to an external API using Python Lambda function

I'm trying to send a multipart/form-data POST request from an AWS lambda function to an external API containing a pdf file.
The client to lambda file upload works, and I can print the buffer content to the console.
The part that doesn't work is the file forwarding to an external API.
This is what i have been trying:
import json
import urllib3
import requests
from io import BytesIO
import base64
def lambda_handler(event, context):
http = urllib3.PoolManager()
encoded_body = base64.b64encode(event['body'].encode('utf-8'))
# multipart_string = "--ce560532019a77d83195f9e9873e16a1\r\nContent-Disposition: form-data; name=\"author\"\r\n\r\nJohn Smith\r\n--ce560532019a77d83195f9e9873e16a1\r\nContent-Disposition: form-data; name=\"file\"; filename=\"file.txt\"\r\nContent-Type: text/plain\r\nExpires: 0\r\n\r\nHello World\r\n--ce560532019a77d83195f9e9873e16a1--\r\n"
# content_type = "multipart/form-data; boundary=ce560532019a77d83195f9e9873e16a1"
# dec = decoder.MultipartDecoder(multipart_string, content_type)
url = "https://app.hubspot.com/api/filemanager/api/v3/files/upload?portalId=XXXXXX"
payload={'options': '{"access":"PUBLIC_NOT_INDEXABLE"}',
'folderPath': '"postman_upload"'}
# files=[
# ('file',('file.pdf',open('/Users/Downloads/file.pdf','rb'),'application/pdf'))
# ]
headers = {
'cookie': '_conv_r=s%3Awww.yahoo.com*m%3Aorganic*t%3A*c%3A; hubspotutk=549ddd47f01a08d6f999bf4e85615f42; __hssrc=1;',
'x-hubspot-csrf-hubspot': 'AAccUftoNFPKG7PGr6tcWR7JA6Rt35lR4D7qCRL3HcK3deuw23-ucJy4oQvE0dYI43bfP2CCKiZM0j7a03XmaC6hy46ExFlA5g',
'authorization': 'Bearer pbl-na1-c23b6031-7da9-4e7d-9516-6c58vc7cd0dc'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files) #TYPE-1
print(response.text)
response = requests.request("POST", url,headers=headers, data=event['body'].encode('utf-8')) #TYPE-2
print(response.text)
return {
'statusCode': 200,
'body': encoded_body
}
But with this when I send the post request I get "415 Media Type not supported" response.
As the pdf/file is being sent as json (bytes) in the request body but it should be just form data with the parameters.
I am not able to achieve that, have already tried many approaches but none worked.
And most of the folks here are uploading the file to S3, which is typically easy. [But I want a post req with multipart file to an external API]
If anyone here has any idea for this or what I am doing wrong. Could you please help. Thanks.

Python API Call authorization returns 401 for over the retrieval failure of JSESSIONID/Cookie/ClientID by request library

I have simulated successfully API calls with my postman client.
Postman client automatically populates the required JSESSIONID, COOKIE, and CLIENT ID.
However, when I try to realize the same with python I get 401. It looks like the session variable of the request API does not hold the required information
I would like to replicate the entire step below with both Postman generated python script and my script
Postman script
In the first POST call, I use my secretKey to request the secret
import requests
url = "https://url.com/v1/session/auth/token?X-Requested-By=Maddy&Content-Type=application/x-www-form-urlencoded"
payload="secret_key=zxcvfc-103f-950d-856d-cxvfdgh&username=myuser001&access_level=FULL"
headers = {
'X-Requested-By': 'Maddy', #This is my header
'Content-Type': 'application/x-www-form-urlencoded', #My header
'Cookie': 'route=e7esaafb42ce234234242347482341f; clientId= zxcvfc-103f-950d-856d-cxvfdg; JSESSIONID=e34cc53d-e99c-4296-a4fe-0d70a246bd11' #Postman generated
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
I get a secret JHNXZasdasdasdasjdakdasdjdalsdjasdladasdlalsdjajsdjaskdjaksjdaskjdjaskdljasj very long
then the second GET call is done with the secret I have received.
import requests
url = "https://url.com/callosum/v1/session/login/token?username=myuser001&auth_token=JHNXZasdasdasdasjdakdasdjdalsdjasdladasdlalsdjajsdjaskdjaksjdaskjdjaskdljasj&redirect_url=https://url.com/callosum/v1/tspublic/v1/user/list"
payload={}
headers = {
'Cookie': 'route=e78as0dad9009q029420349249f; clientId=s0255-6598-5103-dec3-defererer090; JSESSIONID=dfgas8484-659595656-6526-5626-7589898ads'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
#The response contains JSON output with a list of users
Not the above header junk that contains id and session and cookie is generated by the postman
Now this is how my Python script looks like
url = "https://url.com/callosum/v1/session/auth/token?X-Requested-By=Maddy&Content-Type=application/x-www-form-urlencoded"
payload="secret_key=zxcvfc-103f-950d-856d-cxvfdgh&username=myuser001&access_level=FULL"
headers = {
'X-Requested-By': 'Maddy', #These one is mine
'Content-Type': 'application/x-www-form-urlencoded' #these one is mine
}
with requests.session() as s:
secret = s.post(url, data=payload, headers=headers,verify=False).text
#secret contain the lengthy secret for the get call stored in the variable secret
payload1 = {}
#The url2 contains login url and redirect url that contains the user API for get method
url2 = "https://url.com/callosum/v1/session/login/token?username=myuser001&auth_token={}&redirect_url=https://url.com/callosum/v1/tspublic/v1/user/list".format(secret)
r = s.get(url2,data=payload1,verify =False)
#Also tried without payload and with and without header results are the same
print(r.cookies)
print(r.text) #401 unauthroized
I get the secret but not the data. Do let me know if there is something that needs to be added.
Best Regards,
Gabby

How to get temporary AWS credentials via Cognito Identity Pool

I am looking to get temporary AWS credentials through a Cognito Identity Pool to send data to a Kinesis stream through API Gateway. One thing to note is that I am trying to do this without an AWS SDK because the language it will be written in eventually does not have a compatible SDK. I am testing the solution in Python and seem to be missing something as I keep getting a 400 error. Any ideas of what I am doing wrong here?
import requests
url = 'https://cognito-identity.us-east-1.amazonaws.com' #cognito regional endpoint
headers = {
'X-AMZ-TARGET': 'com.amazonaws.cognito.identity.model.AWSCognitoIdentityService.GetCredentialsForIdentity',
'X-AMZ-DATE': '20151020T232759Z'
}
body = {
'IdentityId': 'us-east-1:123456789' #identity id
}
response = requests.post(url = url, data = body, headers = headers)
print(response)
I was able to resolve the issue by adding a content type header, converting the single quotes in the body to double quotes, and wrapping the body dictionary in quotes as well.
import requests
url = 'https://cognito-identity.us-east-1.amazonaws.com' #cognito regional endpoint
headers = {
"CONTENT-TYPE": "application/x-amz-json-1.1",
"X-AMZ-TARGET": "com.amazonaws.cognito.identity.model.AWSCognitoIdentityService.GetCredentialsForIdentity",
"X-AMZ-DATE": "20151020T232759Z"
}
body = '''{
"IdentityId": "123456789"
}'''
response = requests.post(url = url, data = body, headers = headers)
print(response.text)

Swagger API and interaction with python requests

A product was purchased to enable our users to send/receive SMS over HTTP. Now it's my job to build it into our current CMS platform & database. It's got a swagger API.
Here is the documentation for the specific POST request I am trying to send:
POST: Send an SMS Message
Here is my simple python program to test the functionality. I get a generic 500 internal server error response. What am I doing incorrectly?
import requests
API_URL = "https://api.kenect.com/v1/conversations/messages"
headers = {
'x-api-token': '****************',
'x-api-key': '*******************',
'Content-Type': 'application/json',
}
params = {
'contactPhone': '158572968**',
'locationId': '2045',
'messageBody': 'test sms',
'outgoing': 'true',
}
r=requests.post(url = API_URL, headers = headers, params = params)
print(r)
There seems to be 2 issues:
Content type and payload encoding.
You are using params parameter in the post method. params is used with get method for passing data in the URL's query string.
In the post method, depending on the required content type, you need to use either data parameter to send form-encoded data:
r=requests.post(url = API_URL, headers = headers, data = params)
or json parameter to send application/json payload:
r=requests.post(url = API_URL, headers = headers, json = params)
Remove the 'Content-Type' key from your headers dictionary. data and json parameters will set up correct content type automatically.
outgoing is not a valid request parameter for the /v1/conversations/messages resource. This field is from the response object, not the request one. Remove it from your payload.
So to sum up, for form-encoded payload the code should look like this:
import requests
API_URL = "https://api.kenect.com/v1/conversations/messages"
headers = {
'x-api-token': '****************',
'x-api-key': '*******************',
}
params = {
'contactPhone': '158572968**',
'locationId': '2045',
'messageBody': 'test sms',
}
r=requests.post(url = API_URL, headers = headers, data = params)

Receiving incorrect response from posting JSON to an URL

I'm trying to post JSON to an URL but the response seems to be wrong.
url = "www.example123.com/someurl"
mypayload = { //JSON PAYLOAD }
response = request.post(url, post = payload, auth = ("USERNAME", "PASSWORD"))
print(response.content)
But it does not seem to work. What is wrong with the code?
You need the appropriate header for the specifying its JSON data.
Try :
headers_JSON = {'content-type': 'application/json'}
response = request.post(url, JSON = mypayload, headers = headers_JSON, auth = ("USERNAME", "PASSWORD"))
Also note, instead of post = payload, use JSON = payload.
If that doesn't work use:
post = JSON.dumps(payload)
A quick look at the documentation will help : http://docs.python-requests.org/en/master/user/quickstart/
var retval = jQuery.ajax({
type:'post',
url: url,
contentType: 'application/json',
data: JSON.stringify(data)
});
You can see in above jquery ajax we are setting content Type to "application/json"
You can see in your request payload what it is. It all depends upon what your server API is expecting means Content Type.

Categories

Resources