Finding the content length of a multipart image - python

I'm trying to submit a multipart image to a post request and I am frequently getting a "414 Request-URI Too Large" error when trying to post it. I'm wondering if my headers for submitting the photo are incorrect, because I noticed that most posts require content-length, boundaries, etc.
I'm wondering if some of that parameters are supposed to be auto filled or if I'm supposed to submit them myself.
This is a snippet of my code that can give an example of what I'm doing
with open(imageFile, 'rb') as f:
headers = {"Authorization": "Token mytoken", "Content-type": "multipart/form-data"}
r = requests.post('https://api.findface.pro/v1/detect', params={"photo": f},headers=headers)
Sorry if this post isn't formatted correctly, this is my first post on SO.

The image (as a multipart data) can't be sent trough an url parameter.
In your example the "post" request would be this->
https://api.findface.pro/v1/detect/
You should send the data this way to the server:
with open(imageFile, 'rb') as file:
headers = {"Authorization": "Token mytoken",
"Content-type": "multipart/form-data"}
data = {'photo': file}
r = requests.post('https://api.findface.pro/v1/detect', data = data,headers=headers)

Related

Zapier - Input data not able to form payload

I've used Zapier quite a bit, but not real familiar with Python. I grabbed the Python Code for creating a room on Daily.co and want to name the room based on data from a form fill to create a video chat link for applicants. I can create a room with a static name, but not sure how to form the payload part of the response with data from Zapier. The Daily.co formatting is not what I have seen in other examples. I added an input_data called roomname, but can't get it into the payload string. I'm including a screen shot and would appreciate some help since I am a novice on Python.
image of Zapier screen
import requests
url = "https://api.daily.co/v1/rooms"
payload = "{"name":"Room1"}"
headers = {
'content-type': "application/json",
'authorization': "Bearer ad95XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX84dd"
}
response = requests.request("POST", url, data=payload, headers=headers)
print(response.text)
I believe you simply need to remove the outer "" from the payload line. Try:
payload = {'name': 'Room1'}

why sending image in python using form with post is not working

Trying to send an image using Requests package to Flask server using forms with post. But the flask server is not able to parse the key image. How to send the image in proper format with requests using forms.
Flask server.py
#app.route('/api/<model_name>/predict/', methods=['POST'])
def predict(model_name):
if "image" in request.files.keys():
return jsonify({"msg": "key found"})
print("image", request.files)
return str(), 200
Requests client.py
def get_predictions(path):
url = "http://localhost:9020/api/fasterrcnn/predict/"
payload = {"image": (path.name, open(path, "rb"), "image/jpeg")}
headers = {'content-type': "multipart/form-data"}
response = requests.post(
url, data=payload, headers=headers, stream=True)
pprint(response.text)
Could someone please tell me the possible cause and solution? If I've missed out anything, over- or under-emphasized a specific point, let me know in the comments.
requests documentation page states that you should use files= parameter for posting multipart files.
Example:
import requests
def get_predictions(path):
url = "http://localhost:9020/api/fasterrcnn/predict/"
files = {"image": (path.name, open(path, "rb"), "image/jpeg")}
response = requests.post(url, files=files)
pprint(response.text)

How to convert a python post request to a Postman POST request

I have a python post request to a server where my flask app is hosted. It works fine and I am able to get the desired data.
But I want to test the API using POSTMAN. I am unable to do that because I am unfamiliar with POSTMAN to some extent.
Below is the python code that I have.
import requests
import ast
import json
resp1 = {}
url = 'http://myflaskapiurl:port/route'
files = {'file': open(r'file that should be uploaded to the server', 'rb')}
r = requests.post(url, files=files, data={"flag":2})
headers = {
'content-type': "multipart/form-data",
'Content-Type': "application/x-www-form-urlencoded",
'cache-control': "no-cache",
}
resp1 = ast.literal_eval(r.text)
print(resp1)
I am struggling with the question whether the data and file that I am trying to post to the server should be in raw json or form-data or x-www-form-urlencoded section of body. Also what should be the actual structure.
Because every time I POST this data using form-data or x-www-form-urlencoded section of body I get the error saying
werkzeug.exceptions.BadRequestKeyError
werkzeug.exceptions.HTTPException.wrap..newcls: 400 Bad Request: KeyError: 'file'
This is how it should look like:
The "params" tab should be empty, maybe you're adding a second file parameter there?

Python HTTP Post with upload file and headers generated from Postman

I'm using Python 2.7.
I want to make a HTTP POST using requests, where I upload a file and a key that must go in the HTTP Headers.
For that I've used the application Postman, where it works really fine.
On Postman I've added only the necessary header, which is a Authorization with some key.
On the body, Ive choosen form-data and then the key is an input_image, and they the image itself.
Now I want to replicate this into Python2.7, so I've chose to see the Python code on Postman, which was this one:
import requests
url = "https://foo.com/bar/stuff"
payload = "------WebKitFormBoundary7MA4YDxkTrZu1gW\r\nContent-Disposition: form-data; name=\"input_image\"; filename=\"C:\\Test\\projs\\Supermarket\\doritos.jpeg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YDxkTrZu1gW--"
headers = {
'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YDxkTrZu1gW",
'Authorization': "myAuthorizationKey",
'Cache-Control': "no-cache",
'Postman-Token': "0efwd6e8-051c-4ed5-8d6f-7b1bd135f4d5"
}
response = requests.request("POST", url, data=payload, headers=headers)
print(response.text)
This simply doesn't work. It has the same behaviour as if I didn't send any image using Postman. It looks like the payload string is not being send correctly.
Question:
What is wrong with this Postman auto-generation code in order to send a HTTP POST with image upload and with header at the same time in Python?
I think Postman is doing some logic we are not really aware of. But the package requests provide a way to upload images.
files = {'media': open('my_image.jpg', 'rb')}
r = requests.post(url, files=files, headers=hearders)
According to the server you are sending the image to, the parameters name, this code might need to be slightly changed.
the only trick works here is your code should be same as you post request in postman, no extra headers need to be added , your post request should look like the same as it is in postman.
I could do this by changing my file to an image file and then posting it in my post request.
with open('grass-small.png', 'rb') as imageFile:
imageStr = base64.urlsafe_b64encode(imageFile.read())
files = {'document': ('grass-small.png', imageStr ), 'document_type':(None,'grass')}
This worked for me
import requests
url = 'http://iizuka.cs.tsukuba.ac.jp/projects/colorization/web/'
files = {'file': ("my_img_path/myImage.jpeg", open('my_img_path/myImage.jpeg', 'rb'),'image/jpg')}
r = requests.post(url, files=files)

POST multipart-form image with python through rest API call

I am relatively new to python and enjoying every day I program in it. I have been looking around for a possible solution to figure out how to post an image in a multipart-form, binary format, with a form tag. The API I am trying to call is expecting a binary image in a form.
The request payload sample I have is:
----WebkitFormBoundaryM817iTBsSwXz0iv8
Content-Disposition: form-data, name="image"; filename="123BMW.jpg"
Content-Type: image/jpeg
----WebkitFormBoundaryM817iTBsXwxz0iv8
I have tried several ideas based on some basic requests examples.
Any ideas, thoughts or pointers on where to start looking for such a solution?
def Post_Image(urlPath, filePath, fileName):
url = urlPath headers = {'content-type': 'multipart/form-data'}
files = {'file':(fileName, open(filePath,'rb'))}
payload = {"Content-Disposition": "form-data", "name":fileName}
payload = urllib.urlencode(payload)
resp = requests.post(url, data=payload, headers=headers, files= files)
The problem is you're setting both the data and files parameters, this part of the code sample here:
payload = urllib.urlencode(payload)
resp = requests.post(url, data=payload, headers=headers, files= files)
If both are present, and data value is a string, only it will be in the request. Drop it, and the files will be present.

Categories