POST request from Flutter to deployed Azure Flask application not working - python

I am trying to send an image from my flutter mobile app to my ComputerVision flask app.
Everything is also working normally on my local.
After deploying my Flask app using Azure Web service, everything seems to be working fine, using the browser works, POSTMAN works, but whenever I am posting from the Flutter app, I always get this 500 error code.
Peering into the SUKU console, it seems that there is a problem with the PIL package?
2022-11-03T04:22:27.232127482Z: [ERROR] File "/tmp/8dabcd6400b99b6/antenv/lib/python3.9/site-packages/PIL/TiffImagePlugin.py", line 878, in tobytes
2022-11-03T04:22:27.232130983Z: [ERROR] data = ifd.tobytes(offset)
2022-11-03T04:22:27.232134283Z: [ERROR] File "/tmp/8dabcd6400b99b6/antenv/lib/python3.9/site-packages/PIL/TiffImagePlugin.py", line 887, in tobytes
2022-11-03T04:22:27.232137883Z: [ERROR] "<table: %d bytes>" % len(data) if len(data) >= 16 else str(values)
2022-11-03T04:22:27.232142983Z: [ERROR] TypeError: object of type 'int' has no len()
This is the code I'm using to send the POST request (this works fine for the Flask app in local though)
var stream = http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
// get file length
var length = await imageFile.length();
// string to uri
var uri = Uri.parse(ai_url);
// create multipart request
var request = http.MultipartRequest("POST", uri);
// multipart that takes file
var multipartFile = http.MultipartFile('file', stream, length,
filename: basename(imageFile.path));
request.files.add(multipartFile);
Map<String, String> headers = {
"Content-Type": "multipart/form-data",
"Accept-Encoding": "gzip, deflate, br",
"Accept": "*/*",
"Accept": "application/json",
"Connection": "keep-alive"
};
// add file to multipart
request.headers.addAll(headers);
// send
var response = await request.send();
return await response.stream.bytesToString();
And this is the POSTMAN logs (which is working for both deployed and local FLask app)
POST / HTTP/1.1
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Postman-Token: 6e9a5808-7b9a-44a9-a6e3-58509552da11
Host: [...].azurewebsites.net
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: multipart/form-data; boundary=--------------------------040251306687332340508582
Content-Length: 87777
----------------------------040251306687332340508582
Content-Disposition: form-data; name="file"; filename="img.jpg"
<img.jpg>
----------------------------040251306687332340508582--
HTTP/1.1 200 OK
Content-Length: 400
Content-Type: text/html; charset=utf-8
Date: Thu, 03 Nov 2022 04:21:17 GMT
Server: gunicorn
[Response...]
Can anyone help me?

Related

REACT Frontend not talking to backend despite Flask-CORS

I'm writing an application REACT frontend and Flask backend (with Flask-cord installed). When I make a call from the frontend I get an error
Access to fetch at 'http://127.0.0.1:5000/get' from origin 'http://127.0.0.1:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
So I followed this post
https://www.arundhaj.com/blog/definitive-guide-to-solve-cors-access-control-allow-origin-python-flask.html
and configured my application following the instructions.
If I run
$ curl -v -X OPTIONS -H "Origin: http://127.0.0.1:5000" -H "Access-Control-Request-Method: PUT" -H "Access-Control-Request-Headers: Authorization" http://127.0.0.1:5000
I get this response with the right Access-Control-Allow
Trying 127.0.0.1:5000...
* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0)
> OPTIONS / HTTP/1.1
> Host: 127.0.0.1:5000
> User-Agent: curl/7.77.0
> Accept: */*
> Origin: http://127.0.0.1:5000
> Access-Control-Request-Method: PUT
> Access-Control-Request-Headers: Authorization
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 NOT FOUND
< Server: Werkzeug/2.1.1 Python/3.10.4
< Date: Sat, 23 Apr 2022 09:36:22 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 232
< Access-Control-Allow-Origin: http://127.0.0.1:5000
< Access-Control-Allow-Headers: Authorization
< Access-Control-Allow-Methods: GET, OPTIONS, POST, PUT
If I run the same on http://127.0.0.1:3000 I get this
Trying 127.0.0.1:3000...
* Connected to 127.0.0.1 (127.0.0.1) port 3000 (#0)
> OPTIONS / HTTP/1.1
> Host: 127.0.0.1:3000
> User-Agent: curl/7.77.0
> Accept: */*
> Origin: http://127.0.0.1:3000
> Access-Control-Request-Method: PUT
> Access-Control-Request-Headers: Authorization
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
< X-Powered-By: Express
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: *
< Access-Control-Allow-Headers: *
< Content-Security-Policy: default-src 'none'
< X-Content-Type-Options: nosniff
< Content-Type: text/html; charset=utf-8
< Content-Length: 143
< Vary: Accept-Encoding
< Date: Sat, 23 Apr 2022 09:50:15 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
<
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot OPTIONS /</pre>
</body>
</html>
* Connection #0 to host 127.0.0.1 left intact
Of corse if I run the application the same CORS error is popping up. I have the impression that flask-cors is not seen by React.
Here is the flask-cors configuration
api_config = {
"origins": ["http://127.0.0.1:3000"],
"methods": ["OPTIONS", "GET", "POST", "PUT"],
"allow_headers": ['Content-Type', 'Authorization']
}
CORS(app, resources={
r"/*":api_config
})
And I have this in my js file
useEffect(() => {
fetch("http://127.0.0.1:5000/get", {
mode: 'cors',
method: "GET",
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
},
})
.then(resp => resp.json())
.then(resp => console.log(resp))
.catch(error => console.log(error))
}, []);
I have this issue from an angular + flask app run with python3.10 in a macOS.
The same app works perfectly when run with python3.8 on ubuntu.
I have to try to run it with a lower version of python in the macOS computer to check wether is the os or the python version.
Happy to hear I am not the only one with this issue, I hope I will come back to you with some news.

Downloading files to client with django and GCP

I'm trying to download a file from Django to client using GCP. Currently, the request is made from axios, the file is fetched from GCP using url from the model. This file is then downloaded and returned as a HTTP response to the client. Inside the network tab, I can see a 200 OK response and the image is visible in the preview. However, the download is not being saved to the client desktop. I would appreciate any suggestions
Download method:
def download(request, pk):
url = Model.objects.get(id=pk).__dict__["file1"]
storage_client = storage.Client()
bucket = storage_client.get_bucket(setting("GS_MEDIA_BUCKET_NAME"))
blob = storage.Blob(url, bucket)
filename = url.rsplit("/", 1)[1]
file_path = "temp/" + filename
file_to_download = open(file_path, "rb")
mime_type, _ = mimetypes.guess_type(file_path)
response = HttpResponse(file_to_download, content_type=mime_type)
response["Content-Disposition"] = "attachment; filename=%s" % filename
return response
Response headers
HTTP/1.1 200 OK
Date: Fri, 29 Oct 2021 08:01:15 GMT
Server: WSGIServer/0.2 CPython/3.9.7
Content-Type: image/jpeg
Content-Disposition: attachment; filename=default.jpg
Vary: Origin
Access-Control-Allow-Origin: http://localhost:3000
X-Frame-Options: SAMEORIGIN
Content-Length: 10994
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Request headers
GET /api/models/download/26/ HTTP/1.1
Connection: keep-alive
sec-ch-ua: "Chromium";v="94", "Google Chrome";v="94", ";Not A
Brand";v="99"
Accept: application/json, text/plain, */*
sec-ch-ua-mobile: ?1
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5
Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/94.0.4606.81 Mobile Safari/537.36
sec-ch-ua-platform: "Android"
Origin: http://localhost:3000
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
It's a sad day for axios and content-disposition https://medium.com/#drevets/you-cant-prompt-a-file-download-with-the-content-disposition-header-using-axios-xhr-sorry-56577aa706d6
The solution will be along the lines of the following code, from the front-end:
axios({
url: 'http://localhost:5000/static/example.pdf',
method: 'GET',
responseType: 'blob', // important
}).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.pdf');
document.body.appendChild(link);
link.click();
});

Python POST Request Settings Format

I am trying to send a POST request with Python to upload a file. I'm converting the following sample code to Python but I'm not familiar with how to set this up.
POST /path/to/upload/script HTTP/1.0
Connection: Keep-Alive
User-Agent: My Client App v1.0
Host:
https://bulksell.ebay.com/ws/eBayISAPI.dll?FileExchangeUpload
Content-type: multipart/form-data;
boundary=THIS_STRING_SEPARATES
Content-Length: 256
--THIS_STRING_SEPARATES
Content-Disposition: form-data; name="token"
12345678987654321
--THIS_STRING_SEPARATES
Content-Disposition: form-data; name="file";
filename="listings.csv"
Content-Type: text/csv
... contents of listings.csv ...
--THIS_STRING_SEPARATES
I think I need to set the headers as follows:
headers = {
"Connection": "Keep-Alive",
"User-Agent": "My Client App v1.0",
"Host": "https://bulksell.ebay.com/ws/eBayISAPI.dll?FileExchangeUpload"
"Content-type": "multipart/form-data;"
"Content-Length": "256",
"Host": "https://bulksell.ebay.com/ws/eBayISAPI.dll?FileExchangeUpload",
...
}
Do I need to include these --THIS_STRING_SEPERATES strings?
How do I include my token here? The example just sends it alone.
What would be the correct way to format this for a request.post?
Thank you.

Python requests' POST file fails when trying to upload a WordPress Theme to Host

I'm trying to write a python script that would help me install a theme remotely. Unfortunately, the upload part doesn't play nice, trying to do it with requests' POST helpers.
The HTTP headers of a successful upload look like this:
http://127.0.0.1/wordpress/wp-admin/update.php?action=upload-theme
POST /wordpress/wp-admin/update.php?action=upload-theme HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------2455316848522
Content-Length: 2580849
Referer: http://127.0.0.1/wordpress/wp-admin/theme-install.php
Cookie: wordpress_5bd7a9c61cda6e66fc921a05bc80ee93=admin%7C1497659497%7C4a1VklpOs93uqpjylWqckQs80PccH1QMbZqn15lovQu%7Cee7366eea9b5bc9a9d492a664a04cb0916b97b0d211e892875cec86cf43e2f9d; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_5bd7a9c61cda6e66fc921a05bc80ee93=admin%7C1497659497%7C4a1VklpOs93uqpjylWqckQs80PccH1QMbZqn15lovQu%7C9949f19ef5d900daf1b859c0bb4e2129cf86d6a970718a1b63e3b9e56dc5e710; wp-settings-1=libraryContent%3Dbrowse; wp-settings-time-1=1497486698
Connection: keep-alive
Upgrade-Insecure-Requests: 1
-----------------------------2455316848522: undefined
Content-Disposition: form-data; name="_wpnonce"
b1467671e0
-----------------------------2455316848522
Content-Disposition: form-data; name="_wp_http_referer"
/wordpress/wp-admin/theme-install.php
-----------------------------2455316848522
Content-Disposition: form-data; name="themezip"; filename="oedipus_theme.zip"
Content-Type: application/octet-stream
PK
HTTP/1.1 200 OK
Date: Thu, 15 Jun 2017 01:33:25 GMT
Server: Apache/2.4.25 (Win32) OpenSSL/1.0.2j PHP/7.1.1
X-Powered-By: PHP/7.1.1
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
X-Frame-Options: SAMEORIGIN
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
----------------------------------------------------------
To create a simple session for WP, in order to use later for uploads:
global wp_session
def wpCreateSession(uname, upassword, site_link):
"""
:param uname: Username for the login.
:param upaswword: Password for the login.
:param site_link: Site to login on.
:return: Returns a sessions for the said website.
"""
global wp_session
wp_session = requests.session()
wp_session.post(site_link, data={'log' : uname, 'pwd' : upassword})
To upload the said file to WP, using the wp_session global:
def wpUploadTheme(file_name):
global wp_session
try:
with open(file_name, 'rb') as up_file:
r = wp_session.post('http://127.0.0.1/wordpress/wp-admin/update.php', files = {file_name: up_file})
print "Got after try."
finally:
up_file.close()
And this last bit is where it doesn't work, the upload is not successful and I get returned to WordPress' basic 404.
I have also tried requests_toolbelt MultiPart_Encoder to no avail.
Question: 'requests' POST file fails when trying to upload
Check your files dict, your dict is invalid
files = {file_name: up_file}
Maybe you need a full blown files dict, for instance:
files = {'themezip': ('oedipus_theme.zip',
open('oedipus_theme.zip', 'rb'),
'application/octet-stream', {'Expires': '0'})}
From docs.python-requests.org
files = {'file': open('test.jpg', 'rb')}
requests.post(url, files=files)
From SO Answer Upload Image using POST form data in Python-requests

Send excel file for downloading GAE python

I am using Google App Engine with python 2.7. And there is need to generate in-memory xls-file and send it to user for downloading.
I found amount of topics in web, but any of them can't help me.
Related topics that I've tried to use: 1) this is with Blobs, I tried at first, 2) without Blob, 3) with force-download MIME type, also I've tried to use googlecloudstorage (can't find links to topics).
Here is my code:
import StringIO
class ExcelHandler(BaseHandler):
def post(self):
"""Save members to excel document and send to user"""
sheet = pyexcel.Sheet([[1, 2], [3, 4]])
filesheet = StringIO.StringIO()
sheet.save_to_memory('xls', filesheet)
filesheet.close()
self.response.write(sheet)
self.response.headers['Content-Type'] = 'application/force-download'
self.response.headers['Content-Transfer-Encoding'] = 'utf-8'
self.response.headers['Content-Disposition'] = 'attachment; filename=test.xlsx'
The problem is in sending response (not in creating file). I tried different 'Content-Type':
'application/vnd.ms-excel',
'application/download',
'application/force-download',
'application/octet-stream',
'application/vnd.openxmlformats - officedocument.spreadsheetml.sheet'
But the best response I've achieved is as on picture:
I can't enforce my browser to start downloading data from server. I guess there may be something in my Request that should say to server 'Hey, I want to download', but it is only my thoughts, I've not found anything about that. Will appreciate any help!
Here is also my Request:
POST /reg/excel HTTP/1.1
Host: 0.0.0.0:8080
Connection: keep-alive
Content-Length: 0
Accept: */*
Origin: http://0.0.0.0:8080
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
Referer: http://0.0.0.0:8080/competition?dbKey=agpkZXZ- dG1tb3NjchgLEgtDb21wZXRpdGlvbhiAgICAgICgCww
Accept-Encoding: gzip, deflate
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
and Response at debugger:
HTTP/1.1 200 OK
content-disposition: attachment; filename=test.xlsx
content-transfer-encoding: utf-8
cache-control: no-cache
content-type: application/force-download
Content-Length: 64
Server: Development/2.0
Date: Sun, 02 Oct 2016 15:36:20 GMT
EDIT 1: (try answer by voscausa)
Try this:
output = StringIO.StringIO()
.......
self.response.headers[b'Content-Type'] = b'application/vnd.ms-excel; charset=utf-8'
self.response.headers[b'Content-Disposition'] = b'attachment; filename=test.xlsx'
self.response.write(output.getvalue())

Categories

Resources