From 94b4927d8d4ff430a7bca81315708c90df92fd27 Mon Sep 17 00:00:00 2001 From: MoritzWeber Date: Fri, 8 Nov 2024 10:50:38 +0100 Subject: [PATCH] refactor(backend): Replace deprecated `on_startup` and `on_shutdown` --- backend/capellacollab/__main__.py | 32 +++++---- .../capellacollab/core/database/migration.py | 72 ++++++++++--------- backend/capellacollab/metrics.py | 14 ++-- .../toolmodels/backups/runs/interface.py | 2 +- backend/capellacollab/sessions/idletimeout.py | 2 +- 5 files changed, 62 insertions(+), 60 deletions(-) diff --git a/backend/capellacollab/__main__.py b/backend/capellacollab/__main__.py index 0531d32971..6566fbe2d0 100644 --- a/backend/capellacollab/__main__.py +++ b/backend/capellacollab/__main__.py @@ -2,9 +2,9 @@ # SPDX-License-Identifier: Apache-2.0 +import contextlib import logging import os -import typing as t import fastapi import fastapi_pagination @@ -45,33 +45,35 @@ ] -async def startup(): +@contextlib.asynccontextmanager +async def lifespan(_app: fastapi.FastAPI): + del _app + migration.migrate_db(engine, config.database.url) - logging.info("Migrations done - Server is running") - # This is needed to load the Kubernetes configuration at startup + # Load the Kubernetes configuration at startup operators.get_operator() + idletimeout.terminate_idle_sessions_in_background() + pipeline_runs_interface.schedule_refresh_and_trigger_pipeline_jobs() + sessions_auth.initialize_session_pre_authentication() + + metrics.register_metrics() + logging.getLogger("uvicorn.access").disabled = True logging.getLogger("kubernetes.client.rest").setLevel("INFO") + logging.info("Startup completed.") -async def shutdown(): - logging.getLogger("uvicorn.access").disabled = False - logging.getLogger("uvicorn.error").disabled = False + yield + logging.getLogger("uvicorn.access").disabled = False + logging.info("Shutdown completed.") -on_startup: list[t.Callable] = [ - startup, - idletimeout.terminate_idle_sessions_in_background, - pipeline_runs_interface.schedule_refresh_and_trigger_pipeline_jobs, - sessions_auth.initialize_session_pre_authentication, -] app = fastapi.FastAPI( title="Capella Collaboration", version=__version__, - on_startup=on_startup + metrics.metrics_registration, middleware=[ middleware.Middleware( cors.CORSMiddleware, @@ -86,7 +88,7 @@ async def shutdown(): middleware.Middleware(core_logging.LogRequestsMiddleware), middleware.Middleware(starlette_prometheus.PrometheusMiddleware), ], - on_shutdown=[shutdown], + lifespan=lifespan, openapi_url="/api/docs/openapi.json", docs_url="/api/docs/swagger", redoc_url="/api/docs/redoc", diff --git a/backend/capellacollab/core/database/migration.py b/backend/capellacollab/core/database/migration.py index 8b7875918f..ec05df9532 100644 --- a/backend/capellacollab/core/database/migration.py +++ b/backend/capellacollab/core/database/migration.py @@ -52,43 +52,45 @@ def migrate_db(engine, database_url: str): - if os.getenv("ALEMBIC_CONTEXT") != "1": - os.environ["ALEMBIC_CONFIGURE_LOGGER"] = "false" - root_dir = pathlib.Path(__file__).parents[2] + if os.getenv("ALEMBIC_CONTEXT") == "1": + return - # Get current revision of Database. If no revision is available, initialize the database. + os.environ["ALEMBIC_CONFIGURE_LOGGER"] = "false" + root_dir = pathlib.Path(__file__).parents[2] - alembic_cfg = alembic_config.Config(str(root_dir / "alembic.ini")) - alembic_cfg.set_main_option( - "script_location", str(root_dir / "alembic") - ) - alembic_cfg.set_main_option("sqlalchemy.url", database_url) - alembic_cfg.attributes["configure_logger"] = False - - with engine.connect() as conn: - context = migration.MigrationContext.configure(conn) - current_rev = context.get_current_revision() - - session_maker = orm.sessionmaker(bind=engine) - - with session_maker() as session: - if current_rev: - LOGGER.info("Upgrade database to head") - command.upgrade(alembic_cfg, "head") - else: - LOGGER.info("Empty database detected.") - database.Base.metadata.create_all(bind=engine) - LOGGER.info("Database structure creation successful") - command.stamp(alembic_cfg, "head") - initialize_admin_user(session) - initialize_default_project(session) - initialize_coffee_machine_project(session) - - create_tools(session) - create_t4c_instance_and_repositories(session) - create_github_instance(session) - create_default_models(session) - create_coffee_machine_model(session) + # Get current revision of Database. If no revision is available, initialize the database. + + alembic_cfg = alembic_config.Config(str(root_dir / "alembic.ini")) + alembic_cfg.set_main_option("script_location", str(root_dir / "alembic")) + alembic_cfg.set_main_option("sqlalchemy.url", database_url) + alembic_cfg.attributes["configure_logger"] = False + + with engine.connect() as conn: + context = migration.MigrationContext.configure(conn) + current_rev = context.get_current_revision() + + session_maker = orm.sessionmaker(bind=engine) + + with session_maker() as session: + if current_rev: + LOGGER.info("Upgrade database to head") + command.upgrade(alembic_cfg, "head") + else: + LOGGER.info("Empty database detected.") + database.Base.metadata.create_all(bind=engine) + LOGGER.info("Database structure creation successful") + command.stamp(alembic_cfg, "head") + initialize_admin_user(session) + initialize_default_project(session) + initialize_coffee_machine_project(session) + + create_tools(session) + create_t4c_instance_and_repositories(session) + create_github_instance(session) + create_default_models(session) + create_coffee_machine_model(session) + + logging.info("Database migrations completed.") def initialize_admin_user(db: orm.Session): diff --git a/backend/capellacollab/metrics.py b/backend/capellacollab/metrics.py index 58360ffde8..faaded45b1 100644 --- a/backend/capellacollab/metrics.py +++ b/backend/capellacollab/metrics.py @@ -1,16 +1,14 @@ # SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors # SPDX-License-Identifier: Apache-2.0 -import typing as t - import capellacollab.sessions.metrics as sessions_metrics import capellacollab.settings.modelsources.t4c.license_server.metrics as t4c_metrics from capellacollab.core.database import metrics as database_metrics from capellacollab.feedback import metrics as feedback_metrics -metrics_registration: list[t.Callable] = [ - sessions_metrics.register, - t4c_metrics.register, - feedback_metrics.register, - database_metrics.register, -] + +def register_metrics(): + sessions_metrics.register() + t4c_metrics.register() + feedback_metrics.register() + database_metrics.register() diff --git a/backend/capellacollab/projects/toolmodels/backups/runs/interface.py b/backend/capellacollab/projects/toolmodels/backups/runs/interface.py index 2d8dea86a4..29cb3d355b 100644 --- a/backend/capellacollab/projects/toolmodels/backups/runs/interface.py +++ b/backend/capellacollab/projects/toolmodels/backups/runs/interface.py @@ -27,7 +27,7 @@ PIPELINES_TIMEOUT = config.pipelines.timeout -async def schedule_refresh_and_trigger_pipeline_jobs(interval=5): +def schedule_refresh_and_trigger_pipeline_jobs(interval=5): async def loop(): while True: try: diff --git a/backend/capellacollab/sessions/idletimeout.py b/backend/capellacollab/sessions/idletimeout.py index f3a410628d..e377c02719 100644 --- a/backend/capellacollab/sessions/idletimeout.py +++ b/backend/capellacollab/sessions/idletimeout.py @@ -44,7 +44,7 @@ def terminate_idle_session(): operators.get_operator().kill_session(session_id) -async def terminate_idle_sessions_in_background(interval=60): +def terminate_idle_sessions_in_background(interval=60): async def loop(): while True: try: