I´m trying to upload an image with Python 3, this is my upload method:
def load():
headers = {'X-API-Key' : adminTokenSession}
image= {'image': open ('C:/Users/Cesar/Desktop/A-FT-DIVT.jpg', 'rb')}
res = requests.post(activityInfoURL, files= image, headers = headers)
print (res.text)
In the server I check if format is jpg or png like this:
if (files.image[0].headers['content-type'] != 'image/jpeg' && files.image[0].headers['content-type'] != 'image/png') {
logger.warn("Trying to upload a different format file")
res.json({ error: "The file must be an image" })
I´m always getting "The file must be an image" error and I think it´s because headers are not created.
Thanks in advance.
You may want to post an image, instead of an open file descriptor:
headers = {'X-API-Key' : adminTokenSession}
# Note here
with open('C:/Users/Cesar/Desktop/A-FT-DIVT.jpg', 'rb') as f:
image = {'image': f.read()}
# Note: ^^^^^^^^
res = requests.post(activityInfoURL, files= image, headers = headers)
Related
I am trying to trigger an external api from postman by passing the uploadFile in the body as form-data. Below code throws me an error as 'FileNotFoundError: [Errno 2] No such file or directory:'
Note: In postman, uploadFile takes file from my local desktop as input. have also modified the postman settings to allow access for files apart from working directory
Any help would be highly appreciable.
Below is the Code:
#app.route('/upload', methods=['POST'])
#auth.login_required
def post_upload():
payload = {
'table_name': 'incident', 'table_sys_id': request.form['table_sys_id']
}
files = {'file': (request.files['uploadFile'], open(request.files['uploadFile'].filename,
'rb'),'image/jpg', {'Expires': '0'})}
response = requests.post(url, headers=headers, files=files, data=payload)
return jsonify("Success- Attachment uploaded successfully ", 200)
Below code throws me an error as 'FileNotFoundError: [Errno 2] No such file or directory:
Have you defined UPLOAD_FOLDER ? Please see: https://flask.palletsprojects.com/en/latest/patterns/fileuploads/#a-gentle-introduction
i am passing the attribute (upload file) in body as form-data, can this be passed as raw json
You cannot upload files with JSON. But one hacky way to achieve this is to base64 (useful reference) encode the file before sending it. This way you do not upload the file instead you send the file content encoded in base64 format.
Server side:
import base64
file_content = base64.b64decode(request.data['file_buffer_b64'])
Client side:
-> Javascript:
const response = await axios.post(uri, {file_buffer_b64: window.btoa(file)})
-> Python:
import base64
with open(request.data['uploadFile'], "rb") as myfile:
encoded_string = base64.b64encode(myfile.read())
payload = {"file_buffer_b64": encoded_string}
response = requests.post(url, data=payload)
I have to post a file using Multipart upload to a company-internal REST service. The endpoint needs the file as property "file" and it needs an additional property "DestinationPath". Here is what I do:
url = r"http://<Internal IP>/upload"
files = {
"DestinationPath": "/some/where/foo.txt",
"file": open("test.txt", "rb")
}
response = requests.post(url, files=files)
The server complains that it can't get the "DestinationPath". Full error message I receive is:
{'errors': {'DestinationPath': ['The DestinationPath field is required.']},
'status': 400,
'title': 'One or more validation errors occurred.',
'traceId': '00-1993fbc53ab2ee418b683915dd7a440a-2338bd9cf34d414a-00',
'type': 'https://tools.ietf.org/html/rfc7231#section-6.5.1'}
The file upload works in curl, thus it must be python specific.
You might want to try using the data argument instead of files.
response = requests.post(url, data=files)
Thanks to #etemple1 I found the solution to my question:
url = r"http://<Internal IP>/upload"
data = {
"DestinationPath": "/some/where/foo.txt",
}
with open("test.txt", "rb") as content:
files = {
"file": content.read(),
}
response = requests.post(url, data=data, files=files)
The data for the multipart upload needed to be divided between "data" and "files". They are later combined in the body of the http post by the requests library.
I am calling an API that returns the following object as response:
{
"BrokenRules": [],
"ReturnCode": 0,
"ReturnData": "\"UEsDBBQAAAAIAGJAylC560mkEgIAAM4DAAAPABwAeGwvd29ya2Jvb2sueG1sIKIYACigFAAAAAAAAAAAAAAAAAAAAAAAAAAAAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mku.....ASAMAABMAAAAAAAAAAAAAAAAA0P8QAFtDb250ZW50X1R5cGVzXS54bWxQSwUGAAAAAAgACAD9AQAAqAERAAAA\""
}
I am supposed to be able to download an excel file (.xlsx) from the ReturnData object. How do I do that with python 3?
Here is what I have tried, but the file is corrupt and is empty. Any ideas ?
filename = "api_output.xlsx"
response = requests.post(URL, headers=headers, json=data)
res = json.loads(response.json()["ReturnData"])
with open(filename, 'w') as file:
print("writing file")
file.write(res)
So I found the answer:
response = requests.post(URL, headers=headers, json=data)
res = json.loads(response.json()["ReturnData"])
data = base64.b64decode(res)
with open(filename, 'wb') as file:
print("writing file")
file.write(data)
I want to upload image to aws s3 using presigned url and the image is selected by users only.
So I make file input field using flask-wtf filefield.
After user submit the form(PostForm), I want to get the image's data and send to presigned-url.
But I don't know how to get image file's information from the Form.
Please help me!!!
I used example code from below tutorials. But the difference is that I use flask-wtf not local image file.
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-presigned-urls.html
In following code, the problem line is here.
files = {'file': (save_objectname, image.read())}
http_response = requests.post(response['url'], data=response['fields'], files=files)
when I print(image.read())
it shows
b'' <--- nothing...
How can I fix it???
def create_post():
form = PostForm()
save_post_foldername = 'post_images'
if form.validate_on_submit():
if form.post_image.data:
image_file = form.post_image.data
save_post_objectname = generate_filename(image_file)
# Generate a presigned S3 POST URL
post_to_aws_s3(image_file, save_post_foldername, save_post_objectname)
def post_to_aws_s3(image, save_foldername, save_objectname):
fields = {
"acl": "public-read",
"Content-Type": image.content_type
}
conditions = [
{"acl": "public-read"},
{"Content-Type": image.content_type}
]
try:
response = s3_client.generate_presigned_post(
Bucket=S3_BUCKET,
Key=save_foldername+'/'+save_objectname,
Fields=fields,
Conditions=conditions,
ExpiresIn=600
)
print(response)
print(response['url'])
print(image.content_type)
#with open(image, 'rb') as f:
#files = {'file': ('abc.png', f)}
#files = {'file': (image, f)}
files = {'file': (save_objectname, image.read())}
http_response = requests.post(response['url'], data=response['fields'], files=files)
print(image.read())
except ClientError as e:
print("error")
Access_ID and secret ID refer to your aws user access id and secret key, because boto3 will use that to access your aws s3 using the user you assign to it.
s3 = boto3.resource("s3", aws_access_key_id=os.getenv("ACCESS_ID"), aws_secret_access_key=os.getenv("ACCESS_SECRET_ID"))
s3.Bucket("[NAME OF BUCKET]").put_object(Key="images/"+request.files["image"].filename, Body=request.files["image"] )
make sure you you include "enctype" under forms, under jinja, e.g.
<form method="POST" action="" enctype="multipart/form-data">
I need to upload a local picture to an URL.
My curl request looks like : "curl -T 'my_picture' 'the_url' ".
My purpose is to do it in Python, I saw, that I have to use : requests.put().
Everything I did before works nice, but this function give me a lot of trouble.
Solution is probably really easy, but I'm lost.
Thanks for any help.
def apithree(urlupload):
url = urlupload
picture = Image.open("test.png")
headers = {"content-type": "multipart/form-data"}
response = requests.put(url, headers=headers, data=picture)
response = response.json()
print(response)
Other Code I tried
def apithree(urlupload):
url = urlupload
files = {'image': open('test.png', 'rb')}
response = requests.post(url, data=files)
response = response.json()
print(response)
If the command works,the output should be empty, but I always have error messages.
I can add error messages if necessary.
Thanks for any help.
If server accepts multipart/form-data images, you probably need files= parameter for your request:
import requests
files = {'file_name': open(r'C:\data\...\image.png', 'rb')}
r = requests.post(YOUR_URL, files=files) # or requests.put(...)
print(r.status_code, r.json())