tornado icon indicating copy to clipboard operation
tornado copied to clipboard

Raise ValueError("a coroutine was expected, got {!r}".format(main)) when running .../demos/file_upload/file_receiver.py and uploading a file:

Open compressionist opened this issue 2 years ago • 3 comments

When running "file_reciever.py" with Tornado ver. 6.2:

https://github.com/tornadoweb/tornado/blob/master/demos/file_upload/file_reciever.py

and uploading a file:

$ python file_uploader.py file1.txt Traceback (most recent call last): File "/home/ubuntu/codes/tornado/demos/file_upload/file_uploader.py", line 112, in <module> asyncio.run(method(filenames)) File "/home/ubuntu/anaconda3/envs/tornado/lib/python3.10/asyncio/runners.py", line 37, in run raise ValueError("a coroutine was expected, got {!r}".format(main)) ValueError: a coroutine was expected, got <Future pending cb=[coroutine.<locals>.wrapper.<locals>.<lambda>() at /home/ubuntu/anaconda3/envs/tornado/lib/python3.10/site-packages/tornado/gen.py:251]>

I tried to fix it quickly by overwriting the contents of "main" in the main() function by adding "await asyncio.Event().wait()":

async def main(): define("put", type=bool, help="Use PUT instead of POST", group="file uploader")

# Tornado configures logging from command line opts and returns remaining args.
filenames = options.parse_command_line()
if not filenames:
    print("Provide a list of filenames to upload.", file=sys.stderr)
    sys.exit(1)
method = put(filenames) if options.put else post(filenames)
await asyncio.Event().wait()

asyncio.run(main())

But then the program doesn't exit without ctrl-C.

Therefore, to solve this problem (implement graceful exit from Tornado app), I decided to use "asyncio.Condition()", "asyncio.gather(...)" and the Task class inheritance solution, as recommended in https://stackoverflow.com/questions/57708124/correct-usage-of-asyncio-conditions-wait-for-method.

(Please see file_uploader.py.zip)

This solution seems good enough and works well, but it would be exciting if you had a more elegant solution to this problem.

Many thanks for considering my request!

compressionist avatar Sep 02 '22 17:09 compressionist

This file was updated to use asyncio.run() without actually testing it; sorry for the confusion.

The simplest solution (since @gen.coroutine is deprecated) is to replace all the uses of @gen.coroutine in this file with async def (and yield with await).

bdarnell avatar Sep 27 '22 01:09 bdarnell

thanks . it worked

fatemeh-mohseni-AI avatar Aug 21 '23 09:08 fatemeh-mohseni-AI

This file was updated to use asyncio.run() without actually testing it; sorry for the confusion.

The simplest solution (since @gen.coroutine is deprecated) is to replace all the uses of @gen.coroutine in this file with async def (and yield with await).

Thanks -- this works .

RohitDhankar avatar Aug 30 '23 03:08 RohitDhankar