abersheeran / a2wsgi

Convert WSGI app to ASGI app or ASGI app to WSGI app.
Apache License 2.0
226 stars 20 forks source link

Use with Blacksheep? #18

Closed jordemort closed 3 years ago

jordemort commented 3 years ago

Hi, is there any guidance or example of how to use a2wsgi with Blacksheep? I have an app written using aiohttp, and I would like to port it to Blacksheep and run it under a WSGI server, so that I can use it with pywebview.

I've tried breaking things down to be as simple as possible but I can't seem to figure out how to make it work. Here is my test code:

from a2wsgi import ASGIMiddleware
from blacksheep.server import Application
from wsgiref.simple_server import make_server

app = Application()

@app.route("/")
def home():
    return "Hello, world!"

wsgi = ASGIMiddleware(app)

with make_server('', 8000, wsgi) as httpd:
    httpd.serve_forever()

With this, requests just return a 500 error with the message "Server got itself in trouble" - I've tried adding loggers and setting debug=True on the application, but I am unable to get a backtrace out of it to see what exactly is going wrong.

I dug around on the internet but the only examples I could find using ASGIMiddleware all use it with FastAPI.

Can you give me any hints on how to make this work, or how to debug it so I can figure out why it is not working?

abersheeran commented 3 years ago

https://github.com/Neoteroi/BlackSheep/blob/main/blacksheep/server/application.py#L632

https://asgi.readthedocs.io/en/latest/specs/www.html#http-connection-scope

This is blacksheep error. Should .get("raw_path"), not ["raw_path"].

abersheeran commented 3 years ago

a2wsgi strictly implements WSGI, so you can use WSGI to get error messages. This is the code I used.

from a2wsgi import ASGIMiddleware
from blacksheep.server import Application
from wsgiref.simple_server import make_server

app = Application()

@app.route("/")
def home():
    return "Hello, world!"

wsgi = ASGIMiddleware(app)

def debug_wsgi(env, start_response):
    def debug_start_response(status, headers, error):
        if error is not None:
            raise error
        start_response(status, headers, None)
    return wsgi(env, start_response)

with make_server("", 8000, debug_wsgi) as httpd:
    httpd.serve_forever()
jordemort commented 3 years ago

@abersheeran Thanks for the help! I will propose a PR to Blacksheep; can you point me to the bit of the spec that specifies the .get method before I do? I've read through it a bit and it seems to specify what fields the scope object should contain, but I can't find where it says how to interact with the scope object.

abersheeran commented 3 years ago

image

jordemort commented 3 years ago

Ah, I think I understand: The issue is that raw_path is unavailable, not that the specification requires the use of .get - in this case, because Blacksheep does not use .get, it ends up raising a KeyError instead of letting the value default to None.

Is that correct? Thanks again for your help.

abersheeran commented 3 years ago

Yes. It's correct.