aiocoap icon indicating copy to clipboard operation
aiocoap copied to clipboard

Compatibility with flask

Open vnahmias opened this issue 6 years ago • 12 comments

Hello Chris,

i am still working on my app to monitor an IoT environment through CoaP and i get rid iff the django server. I am working now with Angular6+ Flask + python3.6 to build a restFul web application. The issue is when i trigger the coap request from my client through Flask i have an error caused by by an incompatibility between asyncio and flask. I've tried to modify my function to get rid off asyncio but I have issues such as : Failed to fetch resource: 'generator' object has no attribute 'request'

but obviously it's not working so my question is do you think it's possible to request the aiocoap server without using asyncio ?

vnahmias avatar Aug 20 '18 15:08 vnahmias

aiocoap is fundamentally based on asyncio. If you want to use it together with libraries that are not asyncio based themselves, you have two options:

  • Modify that library to use asyncio. (For flask, an attempt has been made as flask-asyncio, but that appears to have failed).
  • Run asyncio and the thread-using part next to each other in separate threads or even processes (you already had a good-looking model of that with multiprocessing).

You can't simply patch the asyncio out of aiocoap; that would be a completely different library with a different API.

chrysn avatar Aug 20 '18 19:08 chrysn

yeah i was guessing that i was opportunist enough to ask you ahah

vnahmias avatar Aug 20 '18 19:08 vnahmias

And, as I should also have mentioned: I recommend you do neither, but simply use a web framework that supports asyncio. I can't recommend one as I have not used any myself, but the asyncio overview page suggests sanic or aiohttp.web

chrysn avatar Aug 20 '18 19:08 chrysn

thanks i will take a look !

vnahmias avatar Aug 20 '18 19:08 vnahmias

BTW the Tornado framework is very mature and has a first class support of asyncio and coroutines. Definately worth to give it a try.

aellwein avatar Aug 21 '18 05:08 aellwein

If this issue is only about to run asyncio functions in synchronous manner, you can use asyncio.get_event_loop().run_until_complete(my_async_function), but you have to pay attention from which thread you are calling this function, eventually you will need to wrap it in asyncio.run_coroutine_threadsafe(...) as described here.

aellwein avatar Aug 21 '18 05:08 aellwein

@aellwein thank you i will give it a try !

vnahmias avatar Aug 21 '18 13:08 vnahmias

@aellwein i've succeeded by calling a synchronous function which calls the async function inside.

vnahmias avatar Aug 21 '18 14:08 vnahmias

@vnahmias nice it works! Just as i said, be careful about calling the asyncio from a Flask request handler. As Flask (possibly) processes requests in WSGI, i.e. one-per-thread, you may run into concurrency issues. In this case, call asyncio functions using run_coroutine_threadsafe().

aellwein avatar Aug 21 '18 17:08 aellwein

thanks for the tip !

vnahmias avatar Aug 21 '18 18:08 vnahmias

you are welcome.

aellwein avatar Aug 21 '18 18:08 aellwein

Not sure if anyone mentioned this already: Quart https://gitlab.com/pgjones/quart

Very close to Flask, but asyncio in its core. And it even provides the very same plugins. In my opinion, it is the successor of it.

grandcat avatar Jan 18 '19 21:01 grandcat