Ejemplo n.º 1
0
    async def run(self, arguments, settings, app):
        host = arguments.host or app.settings.get("host", "0.0.0.0")
        port = arguments.port or app.settings.get("address",
                                                  settings.get("port"))
        loggers = app.settings.get("logging")

        if arguments.asgi_server == "uvicorn":
            from uvicorn import Config  # type: ignore
            from uvicorn import Server  # type: ignore
            from uvicorn.config import LOGGING_CONFIG  # type: ignore

            config = Config(
                app,
                host=host,
                port=port,
                reload=arguments.reload,
                log_config=loggers or LOGGING_CONFIG,
                **app.server_settings.get("uvicorn", {}),
            )
            server = Server(config)
            await server.serve()
        elif arguments.asgi_server == "hypercorn":
            from hypercorn.asyncio import serve  # type: ignore
            from hypercorn.config import Config  # type: ignore
            from hypercorn.logging import CONFIG_DEFAULTS  # type: ignore

            config = Config()
            config.bind = [f"{host}:{port}"]
            config.use_reloader = arguments.reload
            config.logconfig_dict = loggers or CONFIG_DEFAULTS
            config.accesslog = "-"
            config.errorlog = "-"
            await serve(app, config)
        else:
            raise Exception(f"Server {arguments.asgi_server} not supported")
Ejemplo n.º 2
0
    async def async_setup(self):
        with ImportExtensions(required=True):
            from uvicorn import Config, Server

        class UviServer(Server):
            async def setup(self, sockets=None):
                config = self.config
                if not config.loaded:
                    config.load()
                self.lifespan = config.lifespan_class(config)
                self.install_signal_handlers()
                await self.startup(sockets=sockets)
                if self.should_exit:
                    return

            async def serve(self, sockets=None):
                await self.main_loop()
                await self.shutdown(sockets=sockets)

        # change log_level for REST server debugging
        # TODO(Deepankar): The default `websockets` implementation needs the max_size to be set.
        # But uvicorn doesn't expose a config for max_size of a ws message, hence falling back to `ws='wsproto'`
        # Change to 'auto' once https://github.com/encode/uvicorn/pull/538 gets merged,
        # as 'wsproto' is less performant and adds another dependency.
        self._server = UviServer(
            config=Config(app=get_fastapi_app(self.args, self.logger),
                          host=self.args.host,
                          port=self.args.port_expose,
                          ws='wsproto',
                          log_level='critical'))
        await self._server.setup()
        self.logger.success(
            f'{self.__class__.__name__} is listening at: {self.args.host}:{self.args.port_expose}'
        )
Ejemplo n.º 3
0
async def test_unknown_status_code(caplog):
    async def app(scope, receive, send):
        assert scope["type"] == "http"
        await send({
            "type": "http.response.start",
            "status": 599,
            "headers": []
        })
        await send({
            "type": "http.response.body",
            "body": b"",
            "more_body": False
        })

    config = Config(app=app)
    with caplog_for_logger(caplog, "uvicorn.access"):
        async with run_server(config):
            async with httpx.AsyncClient() as client:
                response = await client.get("http://127.0.0.1:8000")

        assert response.status_code == 599
        messages = [
            record.message for record in caplog.records
            if record.name == "uvicorn.access"
        ]
        assert '"GET / HTTP/1.1" 599' in messages.pop()
Ejemplo n.º 4
0
async def test_trace_logging_on_ws_protocol(ws_protocol, caplog):
    async def websocket_app(scope, receive, send):
        assert scope["type"] == "websocket"
        while True:
            message = await receive()
            if message["type"] == "websocket.connect":
                await send({"type": "websocket.accept"})
            elif message["type"] == "websocket.disconnect":
                break

    async def open_connection(url):
        async with websockets.connect(url) as websocket:
            return websocket.open

    config = Config(app=websocket_app, log_level="trace", ws=ws_protocol)
    with caplog_for_logger(caplog, "uvicorn.error"):
        async with run_server(config):
            is_open = await open_connection("ws://127.0.0.1:8000")
        assert is_open
        messages = [
            record.message
            for record in caplog.records
            if record.name == "uvicorn.error"
        ]
        assert any(" - Upgrading to WebSocket" in message for message in messages)
        assert any(" - WebSocket connection made" in message for message in messages)
        assert any(" - WebSocket connection lost" in message for message in messages)
Ejemplo n.º 5
0
async def app(event_loop, db, request):
    globalregistry.reset()
    settings = get_db_settings(request.node)
    app = make_app(settings=settings, loop=event_loop)

    server_settings = settings.get("test_server_settings", {})
    host = server_settings.get("host", "127.0.0.1")
    port = int(server_settings.get("port", 8000))

    from uvicorn import Config, Server

    config = Config(app, host=host, port=port, lifespan="on")
    server = Server(config=config)
    task = asyncio.ensure_future(server.serve(), loop=event_loop)

    while app.app is None and not task.done():
        # Wait for app initialization
        await asyncio.sleep(0.05)

    if task.done():
        task.result()

    await _clear_dbs(app.app.root)

    yield host, port

    server.should_exit = True
    await asyncio.sleep(1)  # There is no other way to wait for server shutdown
    clear_task_vars()
Ejemplo n.º 6
0
async def test_access_log_format(access_log_format, expected_output, caplog):
    async def app(scope, receive, send):  # pragma: no cover
        assert scope["type"] == "http"
        await send(
            {
                "type": "http.response.start",
                "status": 204,
                "headers": [(b"test-response-header", b"response-header-val")],
            }
        )
        await send({"type": "http.response.body", "body": b"", "more_body": False})

    config = Config(app=app, access_log_format=access_log_format)
    with caplog_for_logger(caplog, "uvicorn.access"):
        async with run_server(config):
            async with httpx.AsyncClient() as client:
                response = await client.get(
                    "http://127.0.0.1:8000",
                    headers={"test-request-header": "request-header-val"},
                )
        assert response.status_code == 204

    access_log_messages = [
        record.message for record in caplog.records if "uvicorn.access" in record.name
    ]

    assert len(access_log_messages) == 1
    assert access_log_messages[0] == expected_output
Ejemplo n.º 7
0
def test_access_logging(capsys, http_protocol):
    class App:
        def __init__(self, scope):
            if scope["type"] != "http":
                raise Exception()

        async def __call__(self, receive, send):
            await send({"type": "http.response.start", "status": 204, "headers": []})
            await send({"type": "http.response.body", "body": b"", "more_body": False})

    class CustomServer(Server):
        def install_signal_handlers(self):
            pass

    config = Config(
        app=App,
        loop="asyncio",
        http=http_protocol,
        limit_max_requests=1,
        log_config=test_logging_config,
    )
    server = CustomServer(config=config)
    thread = threading.Thread(target=server.run)
    thread.start()
    while not server.started:
        time.sleep(0.01)
    response = requests.get("http://127.0.0.1:8000")
    assert response.status_code == 204
    thread.join()
    captured = capsys.readouterr()
    assert '"GET / HTTP/1.1" 204' in captured.out
    assert "uvicorn.access" in captured.out
def parse_cli():
    """Run the FastAPI server"""
    # Find numerical value of log level
    try:
        level_num = logger.level(LOG_LEVEL).no
    except ValueError as err:
        logging.error(
            f"Unknown log level {err}. Use one of {', '.join(logger._core.levels)}"
        )
        raise SystemExit()

    # Set up server
    server = Server(
        Config(
            "api.main:app",
            host="0.0.0.0",
            log_level=level_num,
            port=5000,
            proxy_headers=True,
        ), )

    # Set up logging last, to make sure no library overwrites it (they
    # shouldn't, but it happens)
    log.init(LOG_LEVEL)

    # Start server
    server.run()
Ejemplo n.º 9
0
    def __init__(self, name: str, port: Optional[int] = None, **kwargs):
        """
        Args:
            name: the name of the service
            port: the port to bind to when serving, default will bind to an available port
            **kwargs: forwarded to the uvicorn configuration.
        """
        self._app = Starlette(debug=True)
        self._route_lock = Lock()

        # since the main thread won't catch errors in handlers, this class will store any error raised while handling,
        #  and raise them in the main thread as soon as we can
        self._pending_exception: Optional[Exception] = None

        if 'log_config' not in kwargs:
            log_config = deepcopy(uvicorn_logging_config)
            log_config['formatters']['access']['fmt'] = \
                f'%(levelprefix)s {name} %(client_addr)s - "%(request_line)s" %(status_code)s'
            log_config['formatters']['default'][
                'fmt'] = f'%(levelprefix)s {name} %(message)s'
            kwargs['log_config'] = log_config

        kwargs.setdefault('host', '0.0.0.0')

        self._port = port

        config = Config(self._app, **kwargs, port=self._port)
        self._server = Server(config)
        self._serve_thread = Thread(name=f'{name}_thread',
                                    target=self._server.run)
Ejemplo n.º 10
0
async def test_default_default_headers():
    config = Config(app=app, loop="asyncio", limit_max_requests=1)
    async with run_server(config):
        async with httpx.AsyncClient() as client:
            response = await client.get("http://127.0.0.1:8000")
            assert response.headers[
                "server"] == "uvicorn" and response.headers["date"]
Ejemplo n.º 11
0
    def server(self, loop):
        """
            prepare the server and initialize it
            so it be ready to run inside a thread

            this code is inspired by the following link:
                - https://github.com/encode/uvicorn/issues/706#issuecomment-652220153
        """

        app = FastAPI()
        app.x = self
        app.redis = redis.Redis(
            host=self.redis_config["host"],
            port=self.redis_config["port"],
            password=self.redis_config["password"],
            db=self.redis_config["db"]
        )

        app.include_router(routes.router)

        config = Config(
            app=app,
            loop=loop,
            workers=self.server_workers_count,
            port=self.server_listen_port,
            host=self.server_listen_host,
            access_log=self.enable_access_log,
            debug=False
        )

        server = Server(config)

        loop.run_until_complete(server.serve())
Ejemplo n.º 12
0
    async def async_setup(self):
        """
        The async method setup the runtime.

        Setup the uvicorn server.
        """
        with ImportExtensions(required=True):
            from uvicorn import Config, Server

        class UviServer(Server):
            """The uvicorn server."""
            async def setup(self, sockets=None):
                """
                Setup uvicorn server.

                :param sockets: sockets of server.
                """
                config = self.config
                if not config.loaded:
                    config.load()
                self.lifespan = config.lifespan_class(config)
                self.install_signal_handlers()
                await self.startup(sockets=sockets)
                if self.should_exit:
                    return

            async def serve(self, **kwargs):
                """
                Start the server.

                :param kwargs: keyword arguments
                """
                await self.main_loop()

        from jina.helper import extend_rest_interface

        uvicorn_kwargs = self.args.uvicorn_kwargs or {}
        for ssl_file in ['ssl_keyfile', 'ssl_certfile']:
            if getattr(self.args, ssl_file):
                if ssl_file not in uvicorn_kwargs.keys():
                    uvicorn_kwargs[ssl_file] = getattr(self.args, ssl_file)

        self._set_topology_graph()
        self._set_connection_pool()
        self._server = UviServer(config=Config(
            app=extend_rest_interface(
                get_fastapi_app(
                    self.args,
                    topology_graph=self._topology_graph,
                    connection_pool=self._connection_pool,
                    logger=self.logger,
                    metrics_registry=self.metrics_registry,
                )),
            host=__default_host__,
            port=self.args.port,
            ws_max_size=1024 * 1024 * 1024,
            log_level=os.getenv('JINA_LOG_LEVEL', 'error').lower(),
            **uvicorn_kwargs))
        await self._server.setup()
Ejemplo n.º 13
0
def run_api(bot):
    from uvicorn import Server, Config
    web_cog = bot.get_cog("web")
    if web_cog is None:
        return
    server = Server(Config(web_cog.app, host="0.0.0.0", port=1234))
    server.config.setup_event_loop()
    return bot.loop.create_task(server.serve())
Ejemplo n.º 14
0
def start_uvicorn():
    uvicorn_config = Config('src.app:app',
                            host=settings.SERVICE_HOST,
                            port=settings.SERVICE_PORT,
                            log_level=settings.SERVICE_LOG_LEVEL.lower(),
                            loop="asyncio")
    server = Server(config=uvicorn_config)
    server.run()
Ejemplo n.º 15
0
async def do_tests():
    # Create dummy files
    os.makedirs("tests")
    os.makedirs("tests/client")
    os.makedirs("tests/server")
    os.makedirs("tests/server/empty_dir")
    os.makedirs("tests/server/sub1")
    os.makedirs("tests/server/sub1/sub2")
    for filename in [
            "tests/server/f1",
            "tests/server/f2",
            "tests/server/sub1/f3",
            "tests/server/sub1/sub2/f4",
    ]:
        async with aiofiles.open(filename, mode='wb') as f:
            await f.write(os.urandom(10240))

    # Launch server
    http_mv_server.files_path = os.path.join(os.getcwd(), "tests/server")
    http_mv_server.files_pattern = "**"
    server = Server(
        config=Config(http_mv_server.app, host='127.0.0.1', port=8000))
    loop = asyncio.get_event_loop()
    loop.create_task(server.serve(sockets=None))
    await asyncio.sleep(2)  # Create server

    # Launch client
    await http_mv_client("http://127.0.0.1:8000", "tests/client")

    # Check
    files_local = glob.glob("tests/**", recursive=True)
    files_supposed = [
        "tests/client/f1",
        "tests/client/f2",
        "tests/client/sub1/f3",
        "tests/client/sub1/sub2/f4",
        "tests\\client\\f1",
        "tests\\client\\f2",
        "tests\\client\\sub1\\f3",
        "tests\\client\\sub1\\sub2\\f4",
    ]
    for file in files_local:
        if file in files_supposed:
            os.remove(file)
    os.rmdir("tests/client/sub1/sub2")
    os.rmdir("tests/client/sub1")
    os.rmdir("tests/client/")

    # Exit server
    server.handle_exit(None, None)
    await asyncio.sleep(2)  # Gracefully

    # Clean
    os.rmdir("tests/server/sub1/sub2")
    os.rmdir("tests/server/sub1")
    os.rmdir("tests/server/empty_dir")
    os.rmdir("tests/server")
    os.rmdir("tests")
Ejemplo n.º 16
0
 def __init__(self) -> None:
     super().__init__(
         Config(
             app=app,
             host=ServerSettings.get().server_bind_address,
             port=ServerSettings.get().server_port,
             # Configured explicitly with default_logging.yaml or logging.yaml.
             log_config=None,
         ))
Ejemplo n.º 17
0
async def serve():
    config = Config(
        app=APP,
        host=settings.SERVER_HOST,
        port=settings.SERVER_PORT
    )
    server = Server(config)

    await server.serve()
Ejemplo n.º 18
0
def uvicorn_serve(app: 'FastAPI'):
    from uvicorn import Config, Server
    config = Config(app=app,
                    host=server_config.HOST,
                    port=server_config.PORT,
                    loop='uvloop',
                    log_level='error')
    server = Server(config=config)
    server.run()
Ejemplo n.º 19
0
def _start_uvicorn(app: 'FastAPI'):
    config = Config(app=app,
                    host=jinad_args.host,
                    port=jinad_args.port_expose,
                    loop='uvloop',
                    log_level='error')
    server = Server(config=config)
    server.run()
    daemon_logger.info('Goodbye!')
Ejemplo n.º 20
0
def setup_server(host: str, port: int, log_level: str):
    config = Config(
        "tinychronicler:server",
        host=host,
        port=port,
        log_level=log_level,
    )
    server = Server(config=config)
    return server
Ejemplo n.º 21
0
Archivo: main.py Proyecto: yupix/ssm
async def api_run(loop1):
    print('api')
    asyncio.set_event_loop(loop1)
    config = Config(app=app,
                    host="0.0.0.0",
                    loop=loop1,
                    port=5000,
                    reload=True)
    server = Server(config)
    await server.serve()
Ejemplo n.º 22
0
def _start_uvicorn(app: 'FastAPI'):
    config = Config(
        app=app,
        host=jinad_args.host,
        port=jinad_args.port,
        loop='uvloop',
        log_level='error',
    )
    server = Server(config=config)
    server.run()
Ejemplo n.º 23
0
def _start_uvicorn(app: 'FastAPI'):
    from .config import server_config
    config = Config(app=app,
                    host=server_config.HOST,
                    port=server_config.PORT,
                    loop='uvloop',
                    log_level='error')
    server = Server(config=config)
    server.run()
    daemon_logger.info('Bye!')
Ejemplo n.º 24
0
def _start_uvicorn(app: 'FastAPI'):
    config = Config(app=app,
                    host=jinad_args.host,
                    port=jinad_args.port_expose,
                    loop='uvloop',
                    log_level='error')
    server = Server(config=config)
    server.run()
    from jina import __stop_msg__
    daemon_logger.success(__stop_msg__)
Ejemplo n.º 25
0
async def test_disable_default_date_header():
    config = Config(
        app=app,
        loop="asyncio",
        limit_max_requests=1,
        date_header=False,
    )
    async with run_server(config):
        async with httpx.AsyncClient() as client:
            response = await client.get("http://127.0.0.1:8000")
            assert "date" not in response.headers
Ejemplo n.º 26
0
def test_multiprocess_run():
    """
    A basic sanity check.

    Simply run the supervisor against a no-op server, and signal for it to
    quit immediately.
    """
    config = Config(app=None, workers=2)
    supervisor = Multiprocess(config, target=run, sockets=[])
    supervisor.signal_handler(sig=signal.SIGINT, frame=None)
    supervisor.run()
Ejemplo n.º 27
0
    def setup(self):
        with ImportExtensions(required=True):
            from uvicorn import Config, Server

        # change log_level for REST server debugging
        self._server = Server(config=Config(app=self._get_fastapi_app(),
                                            host=self.args.host,
                                            port=self.args.port_expose,
                                            log_level='critical'))
        self.logger.success(
            f'{self.__class__.__name__} is listening at: {self.args.host}:{self.args.port_expose}'
        )
Ejemplo n.º 28
0
async def test_override_server_header_multiple_times():
    config = Config(
        app=app,
        loop="asyncio",
        limit_max_requests=1,
        headers=[("Server", "over-ridden"), ("Server", "another-value")],
    )
    async with run_server(config):
        async with httpx.AsyncClient() as client:
            response = await client.get("http://127.0.0.1:8000")
            assert (response.headers["server"] == "over-ridden, another-value"
                    and response.headers["date"])
Ejemplo n.º 29
0
def test_default_default_headers():
    config = Config(app=app, loop="asyncio", limit_max_requests=1)
    server = Server(config=config)
    thread = threading.Thread(target=server.run)
    thread.start()
    while not server.started:
        time.sleep(0.01)
    response = requests.get("http://127.0.0.1:8000")

    assert response.headers["server"] == "uvicorn" and response.headers["date"]

    thread.join()
Ejemplo n.º 30
0
async def test_add_additional_header():
    config = Config(
        app=app,
        loop="asyncio",
        limit_max_requests=1,
        headers=[("X-Additional", "new-value")],
    )
    async with run_server(config):
        async with httpx.AsyncClient() as client:
            response = await client.get("http://127.0.0.1:8000")
            assert (response.headers["x-additional"] == "new-value"
                    and response.headers["server"] == "uvicorn"
                    and response.headers["date"])