Search code examples
quarthypercorn

Running Quart in production behind Hypercorn


Hey guys I am trying to run Quart in production.

That is my code: setups.py

import quart.flask_patch
from db import *

from http import HTTPStatus
from typing import Optional


import flask.json
from quart import ResponseReturnValue, jsonify, Quart
from quart.ctx import RequestContext
from quart.exceptions import HTTPException
from quart_openapi import Pint

from .confs import __author__, __description__, __mail__, __title__, __version__,SQLALCHEMY_DATABASE_URI
from .routes import initialize_routes
from .user_verify import get_jwks, verify_jwt
        

class PintCustom(Pint):
    def __init__(self, *args, no_openapi: bool = False, **kwargs) -> None:
        self.jwks = get_jwks()
        super().__init__(*args, no_openapi=no_openapi, **kwargs)

    async def preprocess_request(self, request_context: Optional[RequestContext] = None) -> Optional[
        ResponseReturnValue]:
        token = request_context.request.headers.get('Authorization')
        if request_context.request.method != 'OPTIONS':
            try:
                verify_jwt(str(token), self.jwks)
            except Exception:
                raise HTTPException(HTTPStatus.UNAUTHORIZED, 403, 'Log in')

        return await super().preprocess_request(request_context)


def get_app_instance():
    # Initial app.
    # app = Quart(__name__)
    app = PintCustom(__name__, title=__title__, version=__version__, description=__description__,
                     contact_email=__mail__, contact=__author__)


    @app.errorhandler(HTTPException)
    def http_exception(e):
        return jsonify(error=e.name, error_details=e.description), e.status_code

    app.jwks = get_jwks()

    # Initial all the REST API routes.
    initialize_routes(app)


    # DB
    app.config["SQLALCHEMY_DATABASE_URI"] = SQLALCHEMY_DATABASE_URI
    db.init_app(app)

    return app

server.py

__package__ = 'nini'

from .setups import create_app
from .db import db

if __name__ == '__main__':
    app = create_app()
    db.init_app(app)

    app.run(host='127.0.0.1', debug=True)

When I run hypercorn server:app I get :

ModuleNotFoundError: No module named 'nini'

I run the commend under ../nini/server.py

I don't see many tutorials on this. Also tried to run:

pipenv install quart
pipenv shell
export QUART_APP=server:app
quart run

Same error


Solution

  • The app instance on the server module only exists when you invoke that module as the main module, which Hypercorn does not do. Instead you can invoke the factory function, hypercorn "server:create_app()".

    You will likely want to move the db.init_app(app) line to within the create_app function (which I think you've called get_app_instance?) as it is also only called if you invoke server as the main module.

    I don't think you need __package__ = 'nini', which may also cause an issue.