#!/usr/bin/env python3 """ Basebox microservices example app this defines an `app:app` module which is loaded from `main.py` or directly via `uvicorn app:app`. in the latter case configuration can only be passed via OS environment or an env file (`--env-file`), not TOML. For further information, check [uvicorn: deployment](https://www.uvicorn.org/deployment/) """ # stdlib imports from os import environ import argparse import logging # dependencies imports import coloredlogs import uvicorn # app imports import config import consts def setup_logging(): """ Configure logging from LOG_LEVEL environment variable, defaulting to DEBUG. This intentionally does not use the config system to enable log messages from config initialization. Since logging is taken over by uvicorn, this will only be effective during initial startup. :returns: the effective log level """ level = environ.get('LOG_LEVEL', consts.DEFAULT_LOG_LEVEL) logger = logging.getLogger(consts.LOG_ROOT) coloredlogs.install(level=level, logger=logger) return level def parse_args(): """ parse command line arguments """ parser = argparse.ArgumentParser( description='Basebox microservice example') parser.add_argument('-c', '--config-file', type=str, help='config file') return parser.parse_args() def main(): """ application entry point """ # setup logging log_level = setup_logging() # load config args = parse_args() config.load(args.config_file) # inject our application log root into uvicorn's own log config # # discussion: # https://github.com/tiangolo/fastapi/discussions/7457 # https://github.com/encode/uvicorn/issues/491 log_config = uvicorn.config.LOGGING_CONFIG log_config["loggers"][consts.LOG_ROOT] = { "level": log_level.upper(), "handlers": [ "default" ], } # start server uvicorn.run('app:app', log_config=log_config, port=config.int_val('SERVER_PORT'), reload=config.bool_val( 'SERVER_AUTORELOAD', 'False')) if __name__ == "__main__": main()