I am trying to get a function to run asynchronously in my Flask application in Python3.x. I am using the asyncio library and have put async outside of my function declaration, but I am getting an error that reads:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1997, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1615, in full_dispatch_request
return self.finalize_request(rv)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1630, in finalize_request
response = self.make_response(rv)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1740, in make_response
rv = self.response_class.force_type(rv, request.environ)
File "/usr/local/lib/python3.6/site-packages/werkzeug/wrappers.py", line 885, in force_type
response = BaseResponse(*_run_wsgi_app(response, environ))
File "/usr/local/lib/python3.6/site-packages/werkzeug/test.py", line 884, in run_wsgi_app
app_rv = app(environ, start_response)
TypeError: 'coroutine' object is not callable
My code is as follows:
import asyncio
... more function definitions ...
@app.route("/save_to_dbx")
@login_required
async def save_to_dbx():
""" Saves a course to Dropbox as a .zip """
# Creating a .zip file out of the course
zip = zipfile.ZipFile("IoT.zip", "w")
for subdir, dirs, files in os.walk(os.path.join(BASE_PATH, "static/Content/IoT")):
for file in files:
complete__file_path = os.path.join(subdir, file)
print("Writing to Zip:", complete__file_path)
zip.write(complete__file_path, complete__file_path.split("/")[-1])
zip.close()
# Uploading the .zip to Dropbox
f = open(os.path.join(BASE_PATH, "IoT.zip"))
file_size = os.path.getsize(os.path.join(BASE_PATH, "IoT.zip"))
CHUNK_SIZE = 4 * 1024 * 1024
print("Upload file size:", file_size)
if file_size <= CHUNK_SIZE:
print(__dbx_conn__().files_upload(f, "/VOSW-Backup-Testing/IoT.zip"))
else:
upload_session_start_result = __dbx_conn__().files_upload_session_start(f.read(CHUNK_SIZE))
cursor = dropbox.files.UploadSessionCursor(
session_id=upload_session_start_result.session_id,
offset=f.tell())
commit = dropbox.files.CommitInfo(path="/VOSW-Backup-Testing/IoT.zip")
while f.tell() < file_size:
if ((file_size - f.tell()) <= CHUNK_SIZE):
print(__dbx_conn__().files_upload_session_finish(f.read(CHUNK_SIZE), cursor, commit))
else:
__dbx_conn__().files_upload_session_append_v2(f.read(CHUNK_SIZE), cursor)
cursor.offset = f.tell()
return """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Success!</title>
</head>
<body>
<h1>Success!</h1>
</body>"""
What is causing this error?
flask is not asynchronous. It is not directly compatible with asyncio at all, and passing a async function to @app.route in a flask application won't work.
I suggest using quart instead.
You should consider using Sanic. It is really fast and handles async requests very well.
with sanic you can consider this solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With