1

I would like to use Quart on my LiteSpeed server which supports "Python Selector".

I was able to deploy Flask but when I tried to do the same with Quart, it failed. I'm sure it is because Flask runs on WSGI while Quart on ASGI. I tried using things like ASGI to WSGI adapters but it looks like it doesn't work (when I enter the website there is a timeout)

For now, I have tried this passenger_wsgi.py

from main import server
from wsgi_bridge import ASGItoWSGIAdapter

application = ASGItoWSGIAdapter(server)

wsgi_bridge.py

import asyncio
import sys

from http import HTTPStatus


RESPONSE_STATUS_TEXT = {
    code: str(code) for code in range(100, 600)
}
RESPONSE_STATUS_TEXT.update({
    status.value: "%d %s" % (status.value, status.phrase)
    for status in HTTPStatus
})


class ASGItoWSGIAdapter(object):
    """
    Expose an WSGI interface, given an ASGI application.
    """
    def __init__(self, asgi, raise_exceptions=False):
        self.asgi = asgi
        self.raise_exceptions = raise_exceptions
        self.loop = asyncio.get_event_loop()

    def __call__(self, environ, start_response):
        return_bytes = []
        message = self.environ_to_message(environ)
        asgi_coroutine = self.asgi(message)

        async def send(msg):
            if msg['type'] == 'http.response.start':
                status = RESPONSE_STATUS_TEXT[msg['status']]
                headers = [
                    [key.decode('latin-1'), value.decode('latin-1')]
                    for key, value in msg['headers']
                ]
                exc_info = sys.exc_info()
                start_response(status, headers, exc_info)
            elif msg['type'] == 'http.response.body':
                return_bytes.append(msg.get('body', b''))

        async def receive():
            return {
                'type': 'http.request',
                'body': environ['wsgi.input'].read()
            }

        try:
            self.loop.run_until_complete(asgi_coroutine(receive, send))
        except Exception:
            if self.raise_exceptions:
                raise

        return return_bytes

    def environ_to_message(self, environ):
        """
        WSGI environ -> ASGI message
        """
        message = {
            'method': environ['REQUEST_METHOD'].upper(),
            'root_path': environ.get('SCRIPT_NAME', ''),
            'path': environ.get('PATH_INFO', ''),
            'query_string': environ.get('QUERY_STRING', '').encode('latin-1'),
            'http_version': environ.get('SERVER_PROTOCOL', 'http/1.0').split('/', 1)[-1],
            'scheme': environ.get('wsgi.url_scheme', 'http'),
            'raise_exceptions': self.raise_exceptions  # Not actually part of the ASGI spec
        }

        if 'REMOTE_ADDR' in environ and 'REMOTE_PORT' in environ:
            message['client'] = [environ['REMOTE_ADDR'], int(environ['REMOTE_PORT'])]
        if 'SERVER_NAME' in environ and 'SERVER_PORT' in environ:
            message['server'] = [environ['SERVER_NAME'], int(environ['SERVER_PORT'])]

        headers = []
        if environ.get('CONTENT_TYPE'):
            headers.append([b'content-type', environ['CONTENT_TYPE'].encode('latin-1')])
        if environ.get('CONTENT_LENGTH'):
            headers.append([b'content-length', environ['CONTENT_LENGTH'].encode('latin-1')])
        for key, val in environ.items():
            if key.startswith('HTTP_'):
                key_bytes = key[5:].replace('_', '-').lower().encode('latin-1')
                val_bytes = val.encode()
                headers.append([key_bytes, val_bytes])

        message['headers'] = headers

        return message

main.py

import asyncio
from quart import Quart
server = Quart("App")

@server.route('/', methods=['GET', 'POST'])
def ping():
    return "OK!"


async def main():
    await server.run_task()
    
asyncio.run(main())

Application startup file is passenger_wsgi.py and Application Entry point is application

When I go on the website it just shows

Request Timeout

This request takes too long to process, it is timed out by the server. If it should not be timed out, please contact the administrator of this website to increase 'Connection Timeout'. 

Why do I want to use Quart? Because I want to run it alongside my discord bot. It's not only about running it together but also about integration. For example, when someone enters example.com/send it will send a message to the channel.

I'm looking either for a solution for running Quart or a replacement for that.

I hope everything is clear and thanks for help!

NORXND
  • 103
  • 1
  • 8

0 Answers0