def add_databases_to_app(app: FastAPI, dbs: Dict[str, DatabaseDefinition]) -> FastAPI: """Add instances of :class:`Database` as attribute of app. For each database as defined in the ``config.yml`` as external-resource, create a :class:`Database` instance with defined parameters, add this instance to the ``app.databases``-attribute and add ``startup`` and ``shutdown`` handlers to connect / disconnect to the database on app-startup / app-shutdown. Parameters: app: the app to add the database definitions to. dbs: the databases to add to the app. Returns: modified app containing the attribute app.databases and event handler for startup and shutdown for the databases. """ for _, db_definition in dbs.items(): database = Database(dsn=db_definition.dsn, logger=app.logger, min_size=db_definition.min_size, max_size=db_definition.max_size) app.add_event_handler('startup', database.connect) app.add_event_handler('shutdown', database.disconnect) try: app.databases.update({db_definition.name: database}) except AttributeError: app.databases = {db_definition.name: database} return app
def make_app( config_path: Path, version: str, endpoints: List[Endpoint], enable_middlewares: List[str], additional_middlewares: list, ) -> FastAPI: """Create app with endpoints and middlewares. App is configured using the config of the service and defined environment-variables. Also logger is configured and default endpoints and additional endpoints added. Same for middlewares. Note: An app created by this function has additional attributes: * ``app.logger`` * ``app.config`` * ``app.databases`` * ``app.services`` * ``app.mode`` Parameters: config_path: the path for the config file to use for the app. version: current version of the service, should be ``__version__`` variable inside the module ``app`` of your service. endpoints: the endpoints to include to the app. enable_middlewares: list of the middlewares to add. additional_middlewares: list of non default middlewares to add to the app. Returns: the created app. """ # load the config and environment-variables for the service and # combine these information to initialize the app config = collect_config_definition(config_path=config_path) # update mode and logger-definitions with environment-variables if defined # ATTENTION: the environment-variable has the prefix of the servicename config = update_config( env_vars=config.available_environment_variables.env_vars, external_resources_env_vars=( config.available_environment_variables.external_resources_env_vars ), rules_env_vars=config.available_environment_variables.rules_env_vars, config=config, model=Config, ) # convert config-attribute types if necessary config.logger.path = Path(config.logger.path) config.service.readme = Path(config.service.readme) # initialize the app, add combined configuration, mode and logger app = FastAPI( title=f'{config.service.name} [{config.service.mode.upper()}]', description=config.service.readme.read_text(), version=version, ) # add additional attributes to the app like the config and the runtime-mode app.config = config app.mode = config.service.mode # Set the logging-configuration app.logger = customize_logging( config.logger.path / config.logger.filename.format(mode=app.mode), level=config.logger.level, retention=config.logger.retention, rotation=config.logger.rotation, _format=config.logger.format ) # if dependencies for external databases are defined in the config, add # these database-definitions to the app if config.external_resources.databases: app = add_databases_to_app( app, dbs=config.external_resources.databases ) else: app.databases = {} # if dependencies for external services are defined in the config, add # these service-definitions to the app if config.external_resources.services: app = add_services_to_app( app, services=config.external_resources.services ) else: app.services = {} # add default endpoints if defined in the config endpoints = add_default_endpoints(endpoints=endpoints, config=app.config) # include defined routers and middlewares to the app return include_endpoints_and_middlewares_to_app( app=app, endpoints=endpoints, enable_middlewares=enable_middlewares, additional_middlewares=additional_middlewares )