Пример #1
0
def test_message_logger(caplog):
    def app(scope):
        async def asgi(receive, send):
            message = await receive()
            await send({
                "type": "http.response.start",
                "status": 200,
                "headers": []
            })
            await send({
                "type": "http.response.body",
                "body": b"",
                "more_body": False
            })

        return asgi

    caplog.set_level(logging.DEBUG, logger="uvicorn")
    app = MessageLoggerMiddleware(app)
    client = TestClient(app)
    response = client.get("/")
    assert response.status_code == 200
    messages = [record.msg % record.args for record in caplog.records]
    assert sum(['ASGI [1] Initialized' in message
                for message in messages]) == 1
    assert sum(['ASGI [1] Started task' in message
                for message in messages]) == 1
    assert sum(['ASGI [1] Sent' in message for message in messages]) == 1
    assert sum(['ASGI [1] Received' in message for message in messages]) == 2
    assert sum(['ASGI [1] Completed' in message for message in messages]) == 1
    assert sum(
        ['ASGI [1] Raised exception' in message for message in messages]) == 0
Пример #2
0
    def load(self):
        assert not self.loaded

        if isinstance(self.http, str):
            self.http_protocol_class = import_from_string(
                HTTP_PROTOCOLS[self.http])
        else:
            self.http_protocol_class = self.http

        if isinstance(self.ws, str):
            self.ws_protocol_class = import_from_string(WS_PROTOCOLS[self.ws])
        else:
            self.ws_protocol_class = self.ws

        self.lifespan_class = import_from_string(LIFESPAN[self.lifespan])

        try:
            self.loaded_app = import_from_string(self.app)
        except ImportFromStringError as exc:
            self.logger_instance.error("Error loading ASGI app. %s" % exc)
            sys.exit(1)

        if self.wsgi:
            self.loaded_app = WSGIMiddleware(self.loaded_app)
            self.ws_protocol_class = None
        if self.debug:
            self.loaded_app = DebugMiddleware(self.loaded_app)
        if self.logger_instance.level <= logging.DEBUG:
            self.loaded_app = MessageLoggerMiddleware(self.loaded_app)
        if self.proxy_headers:
            self.loaded_app = ProxyHeadersMiddleware(self.loaded_app)

        self.loaded = True
Пример #3
0
async def test_message_logger(caplog):
    async def app(scope, receive, send):
        await receive()
        await send({
            "type": "http.response.start",
            "status": 200,
            "headers": []
        })
        await send({
            "type": "http.response.body",
            "body": b"",
            "more_body": False
        })

    with caplog_for_logger(caplog, "uvicorn.asgi"):
        caplog.set_level(TRACE_LOG_LEVEL, logger="uvicorn.asgi")
        caplog.set_level(TRACE_LOG_LEVEL)

        app = MessageLoggerMiddleware(app)
        async with httpx.AsyncClient(app=app,
                                     base_url="http://testserver") as client:
            response = await client.get("/")
        assert response.status_code == 200
        messages = [record.msg % record.args for record in caplog.records]
        assert sum(["ASGI [1] Started" in message
                    for message in messages]) == 1
        assert sum(["ASGI [1] Send" in message for message in messages]) == 2
        assert sum(["ASGI [1] Receive" in message
                    for message in messages]) == 1
        assert sum(["ASGI [1] Completed" in message
                    for message in messages]) == 1
        assert (sum([
            "ASGI [1] Raised exception" in message for message in messages
        ]) == 0)
Пример #4
0
def test_message_logger(caplog):
    async def app(scope, receive, send):
        message = await receive()
        await send({
            "type": "http.response.start",
            "status": 200,
            "headers": []
        })
        await send({
            "type": "http.response.body",
            "body": b"",
            "more_body": False
        })

    caplog.set_level(TRACE_LOG_LEVEL, logger="uvicorn.asgi")
    caplog.set_level(TRACE_LOG_LEVEL)

    app = MessageLoggerMiddleware(app)
    client = TestClient(app)
    response = client.get("/")
    assert response.status_code == 200
    messages = [record.msg % record.args for record in caplog.records]
    assert sum("ASGI [1] Started" in message for message in messages) == 1
    assert sum("ASGI [1] Send" in message for message in messages) == 2
    assert sum("ASGI [1] Receive" in message for message in messages) == 1
    assert sum("ASGI [1] Completed" in message for message in messages) == 1
    assert sum("ASGI [1] Raised exception" in message
               for message in messages) == 0
Пример #5
0
    def load(self):
        assert not self.loaded

        encoded_headers = [
            (key.lower().encode("latin1"), value.encode("latin1"))
            for key, value in self.headers
        ]
        self.encoded_headers = (
            encoded_headers
            if b"server" in dict(encoded_headers)
            else [(b"server", b"uvicorn")] + encoded_headers
        )  # type: List[Tuple[bytes, bytes]]

        if isinstance(self.http, str):
            self.http_protocol_class = import_from_string(HTTP_PROTOCOLS[self.http])
        else:
            self.http_protocol_class = self.http

        if isinstance(self.ws, str):
            self.ws_protocol_class = import_from_string(WS_PROTOCOLS[self.ws])
        else:
            self.ws_protocol_class = self.ws

        self.lifespan_class = import_from_string(LIFESPAN[self.lifespan])

        try:
            self.loaded_app = import_from_string(self.app)
        except ImportFromStringError as exc:
            self.logger_instance.error("Error loading ASGI app. %s" % exc)
            sys.exit(1)

        if self.interface == "auto":
            if inspect.isclass(self.loaded_app):
                use_asgi_3 = hasattr(self.loaded_app, "__await__")
            elif inspect.isfunction(self.loaded_app):
                use_asgi_3 = asyncio.iscoroutinefunction(self.loaded_app)
            else:
                call = getattr(self.loaded_app, "__call__", None)
                use_asgi_3 = asyncio.iscoroutinefunction(call)
            self.interface = "asgi3" if use_asgi_3 else "asgi2"

        if self.interface == "wsgi":
            self.loaded_app = WSGIMiddleware(self.loaded_app)
            self.ws_protocol_class = None
        elif self.interface == "asgi2":
            self.loaded_app = ASGI2Middleware(self.loaded_app)

        if self.debug:
            self.loaded_app = DebugMiddleware(self.loaded_app)
        if self.logger_instance.level <= logging.DEBUG:
            self.loaded_app = MessageLoggerMiddleware(self.loaded_app)
        if self.proxy_headers:
            self.loaded_app = ProxyHeadersMiddleware(self.loaded_app)

        self.loaded = True
Пример #6
0
    def load(self):
        assert not self.loaded

        if self.logger is None:
            self.logger_instance = get_logger(self.log_level)
        else:
            self.logger_instance = self.logger

        if isinstance(self.http, str):
            self.http_protocol_class = import_from_string(HTTP_PROTOCOLS[self.http])
        else:
            self.http_protocol_class = self.http

        if isinstance(self.ws, str):
            self.ws_protocol_class = import_from_string(WS_PROTOCOLS[self.ws])
        else:
            self.ws_protocol_class = self.ws

        self.lifespan_class = import_from_string(LIFESPAN[self.lifespan])

        try:
            self.loaded_app = import_from_string(self.app)
        except ImportFromStringError as exc:
            self.logger_instance.error("Error loading ASGI app. %s" % exc)
            sys.exit(1)

        if self.wsgi:
            self.loaded_app = WSGIMiddleware(self.loaded_app)
            self.ws_protocol_class = None
        if self.debug:
            self.loaded_app = DebugMiddleware(self.loaded_app)
        if self.logger_instance.level <= logging.DEBUG:
            self.loaded_app = MessageLoggerMiddleware(self.loaded_app)
        if self.proxy_headers:
            self.loaded_app = ProxyHeadersMiddleware(self.loaded_app)

        if self.ssl_keyfile or self.ssl_certfile:
            self.ssl = create_ssl_context(
                keyfile=self.ssl_keyfile,
                certfile=self.ssl_certfile,
                ssl_version=self.ssl_version,
                cert_reqs=self.ssl_cert_reqs,
                ca_certs=self.ssl_ca_certs,
                ciphers=self.ssl_ciphers,
            )
        else:
            self.ssl = None

        self.loaded = True
Пример #7
0
def test_message_logger_exc(caplog):
    async def app(scope, receive, send):
        raise RuntimeError()

    caplog.set_level(logging.DEBUG, logger="uvicorn")
    app = MessageLoggerMiddleware(app)
    client = TestClient(app)
    with pytest.raises(RuntimeError):
        client.get("/")
    messages = [record.msg % record.args for record in caplog.records]
    assert sum(["ASGI [1] Started" in message for message in messages]) == 1
    assert sum(["ASGI [1] Sent" in message for message in messages]) == 0
    assert sum(["ASGI [1] Received" in message for message in messages]) == 0
    assert sum(["ASGI [1] Completed" in message for message in messages]) == 0
    assert sum(["ASGI [1] Raised exception" in message for message in messages]) == 1
Пример #8
0
    def load(self):
        assert not self.loaded

        if isinstance(self.http, str):
            self.http_protocol_class = import_from_string(
                HTTP_PROTOCOLS[self.http])
        else:
            self.http_protocol_class = self.http

        if isinstance(self.ws, str):
            self.ws_protocol_class = import_from_string(WS_PROTOCOLS[self.ws])
        else:
            self.ws_protocol_class = self.ws

        self.lifespan_class = import_from_string(LIFESPAN[self.lifespan])

        try:
            self.loaded_app = import_from_string(self.app)
        except ImportFromStringError as exc:
            self.logger_instance.error("Error loading ASGI app. %s" % exc)
            sys.exit(1)

        if self.interface == "auto":
            if inspect.isclass(self.loaded_app):
                use_asgi_3 = hasattr(self.loaded_app, "__await__")
            elif inspect.isfunction(self.loaded_app):
                use_asgi_3 = asyncio.iscoroutinefunction(self.loaded_app)
            else:
                call = getattr(self.loaded_app, "__call__", None)
                use_asgi_3 = asyncio.iscoroutinefunction(call)
            self.interface = "asgi3" if use_asgi_3 else "asgi2"

        if self.interface == "wsgi":
            self.loaded_app = WSGIMiddleware(self.loaded_app)
            self.ws_protocol_class = None
        elif self.interface == "asgi3":
            self.loaded_app = ASGI3Middleware(self.loaded_app)

        if self.debug:
            self.loaded_app = DebugMiddleware(self.loaded_app)
        if self.logger_instance.level <= logging.DEBUG:
            self.loaded_app = MessageLoggerMiddleware(self.loaded_app)
        if self.proxy_headers:
            self.loaded_app = ProxyHeadersMiddleware(self.loaded_app)

        self.loaded = True
Пример #9
0
async def test_message_logger_exc(caplog):
    async def app(scope, receive, send):
        raise RuntimeError()

    caplog.set_level(TRACE_LOG_LEVEL, logger="uvicorn.asgi")
    caplog.set_level(TRACE_LOG_LEVEL)
    app = MessageLoggerMiddleware(app)
    async with httpx.AsyncClient(app=app,
                                 base_url="http://testserver") as client:
        with pytest.raises(RuntimeError):
            await client.get("/")
    messages = [record.msg % record.args for record in caplog.records]
    assert sum(["ASGI [1] Started" in message for message in messages]) == 1
    assert sum(["ASGI [1] Send" in message for message in messages]) == 0
    assert sum(["ASGI [1] Receive" in message for message in messages]) == 0
    assert sum(["ASGI [1] Completed" in message for message in messages]) == 0
    assert sum(
        ["ASGI [1] Raised exception" in message for message in messages]) == 1
Пример #10
0
def test_message_logger_scope_exc(caplog):
    def app(scope):
        raise RuntimeError()

    caplog.set_level(logging.DEBUG)
    app = MessageLoggerMiddleware(app)
    client = TestClient(app)
    with pytest.raises(RuntimeError):
        client.get("/")
    messages = [record.msg % record.args for record in caplog.records]
    assert sum(['ASGI [1] Initialized' in message
                for message in messages]) == 1
    assert sum(['ASGI [1] Started task' in message
                for message in messages]) == 0
    assert sum(['ASGI [1] Sent' in message for message in messages]) == 0
    assert sum(['ASGI [1] Received' in message for message in messages]) == 0
    assert sum(['ASGI [1] Completed' in message for message in messages]) == 0
    assert sum(
        ['ASGI [1] Raised exception' in message for message in messages]) == 1
Пример #11
0
    def run(self):
        app = self.wsgi

        if self.log.level <= logging.DEBUG:
            app = MessageLoggerMiddleware(app)

        loop = asyncio.get_event_loop()

        self.lifespan = Lifespan(app, self.log)
        if self.lifespan.is_enabled:
            loop.create_task(self.lifespan.run())
            loop.run_until_complete(self.lifespan.wait_startup())
        else:
            self.log.debug(
                "Lifespan protocol is not recognized by the application")

        loop.create_task(self.create_servers(loop, app))
        loop.create_task(self.tick(loop))
        loop.run_forever()
        sys.exit(self.exit_code)
Пример #12
0
    def __init__(
        self,
        app,
        host="127.0.0.1",
        port=8000,
        uds=None,
        fd=None,
        loop="auto",
        http="auto",
        ws="auto",
        log_level="info",
        logger=None,
        access_log=True,
        wsgi=False,
        debug=False,
        proxy_headers=False,
        root_path="",
        limit_concurrency=None,
        limit_max_requests=None,
        disable_lifespan=False,
        timeout_keep_alive=5,
        install_signal_handlers=True,
    ):
        self.app = app
        self.host = host
        self.port = port
        self.uds = uds
        self.fd = fd
        self.loop = loop
        self.http = http
        self.ws = ws
        self.log_level = log_level
        self.logger = logger
        self.access_log = access_log
        self.wsgi = wsgi
        self.debug = debug
        self.proxy_headers = proxy_headers
        self.root_path = root_path
        self.limit_concurrency = limit_concurrency
        self.limit_max_requests = limit_max_requests
        self.disable_lifespan = disable_lifespan
        self.timeout_keep_alive = timeout_keep_alive
        self.install_signal_handlers = install_signal_handlers

        if fd is None:
            self.sock = None
        else:
            self.host = None
            self.port = None
            self.sock = socket.fromfd(fd, socket.AF_UNIX, socket.SOCK_STREAM)

        if self.logger is None:
            self.logger = get_logger(log_level)
        else:
            assert log_level == "info", "Cannot set both 'logger' and 'log_level'"

        if isinstance(http, str):
            self.http_protocol_class = import_from_string(HTTP_PROTOCOLS[http])
        else:
            self.http_protocol_class = http

        if isinstance(ws, str):
            self.ws_protocol_class = import_from_string(WS_PROTOCOLS[ws])
        else:
            self.ws_protocol_class = ws

        if isinstance(self.loop, str):
            loop_setup = import_from_string(LOOP_SETUPS[loop])
            self.loop = loop_setup()

        try:
            self.app = import_from_string(self.app)
        except ImportFromStringError as exc:
            click.echo("Error loading ASGI app. %s" % exc)
            sys.exit(1)

        if self.wsgi:
            self.app = WSGIMiddleware(self.app)
            self.ws_protocol_class = None
        if self.debug:
            self.app = DebugMiddleware(self.app)
        if self.logger.level <= logging.DEBUG:
            self.app = MessageLoggerMiddleware(self.app)
        if self.proxy_headers:
            self.app = ProxyHeadersMiddleware(self.app)
Пример #13
0
def run(
    app,
    host="127.0.0.1",
    port=8000,
    uds=None,
    fd=None,
    loop="auto",
    http="auto",
    ws="auto",
    log_level="info",
    access_log=True,
    wsgi=False,
    debug=False,
    proxy_headers=False,
    root_path="",
    limit_concurrency=None,
    limit_max_requests=None,
    timeout_keep_alive=5,
    install_signal_handlers=True,
    ready_event=None,
):

    if fd is None:
        sock = None
    else:
        host = None
        port = None
        sock = socket.fromfd(fd, socket.AF_UNIX, socket.SOCK_STREAM)

    logger = get_logger(log_level)
    http_protocol_class = import_from_string(HTTP_PROTOCOLS[http])
    ws_protocol_class = import_from_string(WS_PROTOCOLS[ws])

    if isinstance(loop, str):
        loop_setup = import_from_string(LOOP_SETUPS[loop])
        loop = loop_setup()

    try:
        app = import_from_string(app)
    except ImportFromStringError as exc:
        click.echo("Error loading ASGI app. %s" % exc)
        sys.exit(1)

    if wsgi:
        app = WSGIMiddleware(app)
        ws_protocol_class = None
    if debug:
        app = DebugMiddleware(app)
    if logger.level <= logging.DEBUG:
        app = MessageLoggerMiddleware(app)
    if proxy_headers:
        app = ProxyHeadersMiddleware(app)

    connections = set()
    tasks = set()
    state = {"total_requests": 0}

    def create_protocol():
        return http_protocol_class(
            app=app,
            loop=loop,
            logger=logger,
            access_log=access_log,
            connections=connections,
            tasks=tasks,
            state=state,
            ws_protocol_class=ws_protocol_class,
            root_path=root_path,
            limit_concurrency=limit_concurrency,
            timeout_keep_alive=timeout_keep_alive,
        )

    server = Server(
        app=app,
        host=host,
        port=port,
        uds=uds,
        sock=sock,
        logger=logger,
        loop=loop,
        connections=connections,
        tasks=tasks,
        state=state,
        limit_max_requests=limit_max_requests,
        create_protocol=create_protocol,
        on_tick=http_protocol_class.tick,
        install_signal_handlers=install_signal_handlers,
        ready_event=ready_event,
    )
    server.run()
Пример #14
0
    def load(self):
        assert not self.loaded

        if self.is_ssl:
            self.ssl = create_ssl_context(
                keyfile=self.ssl_keyfile,
                certfile=self.ssl_certfile,
                password=self.ssl_keyfile_password,
                ssl_version=self.ssl_version,
                cert_reqs=self.ssl_cert_reqs,
                ca_certs=self.ssl_ca_certs,
                ciphers=self.ssl_ciphers,
            )
        else:
            self.ssl = None

        encoded_headers = [
            (key.lower().encode("latin1"), value.encode("latin1"))
            for key, value in self.headers
        ]
        self.encoded_headers = (
            encoded_headers
            if b"server" in dict(encoded_headers)
            else [(b"server", b"uvicorn")] + encoded_headers
        )  # type: List[Tuple[bytes, bytes]]

        if isinstance(self.http, str):
            self.http_protocol_class = import_from_string(HTTP_PROTOCOLS[self.http])
        else:
            self.http_protocol_class = self.http

        if isinstance(self.ws, str):
            self.ws_protocol_class = import_from_string(WS_PROTOCOLS[self.ws])
        else:
            self.ws_protocol_class = self.ws

        self.lifespan_class = import_from_string(LIFESPAN[self.lifespan])

        try:
            self.loaded_app = import_from_string(self.app)
        except ImportFromStringError as exc:
            logger.error("Error loading ASGI app. %s" % exc)
            sys.exit(1)

        if self.interface == "auto":
            if inspect.isclass(self.loaded_app):
                use_asgi_3 = hasattr(self.loaded_app, "__await__")
            elif inspect.isfunction(self.loaded_app):
                use_asgi_3 = asyncio.iscoroutinefunction(self.loaded_app)
            else:
                call = getattr(self.loaded_app, "__call__", None)
                use_asgi_3 = asyncio.iscoroutinefunction(call)
            self.interface = "asgi3" if use_asgi_3 else "asgi2"

        if self.interface == "wsgi":
            self.loaded_app = WSGIMiddleware(self.loaded_app)
            self.ws_protocol_class = None
        elif self.interface == "asgi2":
            self.loaded_app = ASGI2Middleware(self.loaded_app)

        if self.debug:
            self.loaded_app = DebugMiddleware(self.loaded_app)
        if logger.level <= TRACE_LOG_LEVEL:
            self.loaded_app = MessageLoggerMiddleware(self.loaded_app)
        if self.proxy_headers:
            self.loaded_app = ProxyHeadersMiddleware(
                self.loaded_app, trusted_hosts=self.forwarded_allow_ips
            )

        self.loaded = True
Пример #15
0
    def load(self) -> None:
        assert not self.loaded

        if self.is_ssl:
            assert self.ssl_certfile
            self.ssl: Optional[ssl.SSLContext] = create_ssl_context(
                keyfile=self.ssl_keyfile,
                certfile=self.ssl_certfile,
                password=self.ssl_keyfile_password,
                ssl_version=self.ssl_version,
                cert_reqs=self.ssl_cert_reqs,
                ca_certs=self.ssl_ca_certs,
                ciphers=self.ssl_ciphers,
            )
        else:
            self.ssl = None

        encoded_headers = [(key.lower().encode("latin1"),
                            value.encode("latin1"))
                           for key, value in self.headers]
        self.encoded_headers = ([(b"server", b"uvicorn")] + encoded_headers
                                if b"server" not in dict(encoded_headers)
                                and self.server_header else encoded_headers)

        if isinstance(self.http, str):
            http_protocol_class = import_from_string(HTTP_PROTOCOLS[self.http])
            self.http_protocol_class: Type[
                asyncio.Protocol] = http_protocol_class
        else:
            self.http_protocol_class = self.http

        if isinstance(self.ws, str):
            ws_protocol_class = import_from_string(WS_PROTOCOLS[self.ws])
            self.ws_protocol_class: Optional[Type[
                asyncio.Protocol]] = ws_protocol_class
        else:
            self.ws_protocol_class = self.ws

        self.lifespan_class = import_from_string(LIFESPAN[self.lifespan])

        try:
            self.loaded_app = import_from_string(self.app)
        except ImportFromStringError as exc:
            logger.error("Error loading ASGI app. %s" % exc)
            sys.exit(1)

        try:
            self.loaded_app = self.loaded_app()
        except TypeError as exc:
            if self.factory:
                logger.error("Error loading ASGI app factory: %s", exc)
                sys.exit(1)
        else:
            if not self.factory:
                logger.warning(
                    "ASGI app factory detected. Using it, "
                    "but please consider setting the --factory flag explicitly."
                )

        if self.interface == "auto":
            if inspect.isclass(self.loaded_app):
                use_asgi_3 = hasattr(self.loaded_app, "__await__")
            elif inspect.isfunction(self.loaded_app):
                use_asgi_3 = asyncio.iscoroutinefunction(self.loaded_app)
            else:
                call = getattr(self.loaded_app, "__call__", None)
                use_asgi_3 = asyncio.iscoroutinefunction(call)
            self.interface = "asgi3" if use_asgi_3 else "asgi2"

        if self.interface == "wsgi":
            self.loaded_app = WSGIMiddleware(self.loaded_app)
            self.ws_protocol_class = None
        elif self.interface == "asgi2":
            self.loaded_app = ASGI2Middleware(self.loaded_app)

        if self.debug:
            self.loaded_app = DebugMiddleware(self.loaded_app)
        if logger.level <= TRACE_LOG_LEVEL:
            self.loaded_app = MessageLoggerMiddleware(self.loaded_app)
        if self.proxy_headers:
            self.loaded_app = ProxyHeadersMiddleware(
                self.loaded_app, trusted_hosts=self.forwarded_allow_ips)

        self.loaded = True