Python Forum
Wsgiref with asyncio ?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Wsgiref with asyncio ?
#7
(Oct-31-2022, 02:50 AM)wavic Wrote: I am not familiar with the plain WSGI at all. Never used directly. So I can only guess how it works.

But first something about asycnio.

run_until_complete returns the result of a future object ( maincoro ) - in that case it will be [str('Test of requisition http ?').encode('utf-8')]. Which is a list BTW. The returned result will be the returned one from the coroutine ( maincoro ) object. It does not return a callable function which you can use into the with statement.

I think make_server runs the server and waits for a request. Then when happens it calls the hander ( maincoro is your handler ) and its returned object is sent back. Instead of giving it a function to execute on a request, you are giving it [str('Test of requisition http ?').encode('utf-8')] .

The error is because maincoro is executed before the with statement which takes the request and provides the environ as an argument to maincoro. The environ object doesn't exist yet at the execution of maincoro.

I guess you are not quite familiar how asyncio and the event loop work.

asyncio is not a small library. I barely touch it sometimes. When I need some async calls. Most of the time I use 3rd party libraries to do web requests for example. Lke aiohttp or httpx... One may call them frameworks. Anyway.

During figuring out for myself what is going on with such a low-level library as WSGI I came across two I think useful web pages. First is how to make a framework using WSGI. Perhaps it explains a lot of its machinery. I don't have time to dig into it.

The second one is about asynchronous WSGI called ASGI which I think you can use for your purposes. Making an asynchronous framework using a low-level library. At least you will be able to see how they wrap WSGI in order to work with asyncio.

Apologize my English Wink

The output I found was to define a simple intermediate function (maininter) with parameters (environ, start_response) and that is triggered when the http request happens, so that the object (environ) is available to be able to manipulate it.

In the (maininter) function, notice that I try to capture event loop via ( get_event_loop() ) but I get the message ( Deprecation Warning: There is no current event loop ) ? Imagining in getting the event loop ( http request ) I define the loop to run until it ends through the method ( run_until_complete() ), triggering the asynchronous function (maincoro) with passing parameters (environ, start_response) so that it executes the code without problems, follow the code below:

# Native Module : asyncio — Asynchronous I/O -> https://docs.python.org/3/library/asyncio.html#module-asyncio
from asyncio import get_event_loop
# Native Module : wsgiref.simple_server -> ( https://docs.python.org/3/library/wsgiref.html#module-wsgiref )
from wsgiref.simple_server import make_server
# Native Module :
import inspect, threading


def maininter(environ, start_response):

    # Function -> capture the loop
    loop = get_event_loop()
    # Function -> run until it terminate the loop and trigger the coroutine :
    return loop.run_until_complete(maincoro(environ, start_response, loop))

# Function -> convert function to coroutine and be able to run concurrently ( asynchronous )
async def maincoro(environ, start_response, loop):

    iscoro = inspect.iscoroutinefunction(maincoro)
    thread = threading.active_count()

    status = '200 OK'  # HTTP Status
    headers = [('Content-type', 'text/plain; charset=utf-8')]  # HTTP Headers
    start_response(status, headers)

    # The returned object is going to be printed
    return [str(f'It is asynchronous request http ? ( Response: {iscoro} ), ( Thread Number : {thread} ), ( Loop : {loop} )').encode('utf-8')]

# step 1º -> start the test server
# step 2º -> trigger function of the main coroutine via http request
# step 3º -> capture the function loop in execution

with make_server('', 8000, maininter) as httpd:

    print(f'Serving on port 8000...')
    # Serve until process is killed
    httpd.serve_forever()
( ☉☉ ) The code works, but I still have doubts?

• Why this message ( Deprecation Warning: There is no current event loop ) ?
• Does the code really work asynchronously to answer http requests?
Reply


Messages In This Thread
Wsgiref with asyncio ? - by JohnnyCoffee - Oct-27-2022, 06:59 PM
RE: Wsgiref with asyncio ? - by wavic - Oct-28-2022, 11:17 AM
RE: Wsgiref with asyncio ? - by JohnnyCoffee - Oct-28-2022, 02:12 PM
RE: Wsgiref with asyncio ? - by wavic - Oct-28-2022, 02:59 PM
RE: Wsgiref with asyncio ? - by JohnnyCoffee - Oct-30-2022, 10:36 PM
RE: Wsgiref with asyncio ? - by wavic - Oct-31-2022, 02:50 AM
RE: Wsgiref with asyncio ? - by JohnnyCoffee - Oct-31-2022, 03:42 PM
RE: Wsgiref with asyncio ? - by wavic - Oct-31-2022, 03:47 PM
RE: Wsgiref with asyncio ? - by JohnnyCoffee - Nov-01-2022, 08:35 PM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020