argos/argos/server/main.py
Alexis Métaireau 43f8aabb2c Refactor server codebase for testing.
- Restructured server module to separate the application creation and configuration.
- Moved code dealing with SQLAlchemy database
  setup and teardown to the main application file.
- Moved functions related to configuration file loading to `argos.server.settings`.
- Fixed SQLAchemy expressions in `argos.server.queries`.
- Implemented a more granular system of setting checks' schedule on the server.
- Introduced frequency scheduling on per-website basis in the YAML config.
- Introduced Pytest fixtures for handling test database and authorized HTTP client in `tests/conftest.py`.
- Included a first test for the api
- Implemented changes to models to accommodate changes to task scheduling.
- Fixed errors concerning database concurrency arising from changes to the application setup.
2023-10-11 23:52:33 +02:00

78 lines
1.9 KiB
Python

import sys
from fastapi import FastAPI
from pydantic import ValidationError
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from argos.logging import logger
from argos.server import models, queries
from argos.server.api import api as api_router
from argos.server.settings import get_app_settings, read_yaml_config
def get_application() -> FastAPI:
settings = get_app_settings()
app = FastAPI()
config = read_config(app, settings)
app.state.config = config
app.add_event_handler(
"startup",
create_start_app_handler(app, settings),
)
app.add_event_handler(
"shutdown",
create_stop_app_handler(app),
)
app.include_router(api_router)
return app
def create_start_app_handler(app, settings):
async def read_config_and_populate_db():
setup_database(app, settings)
db = await connect_to_db(app, settings)
await queries.update_from_config(db, app.state.config)
return read_config_and_populate_db
async def connect_to_db(app, settings):
app.state.db = app.state.SessionLocal()
return app.state.db
def create_stop_app_handler(app):
async def stop_app():
app.state.db.close()
return stop_app
def read_config(app, settings):
try:
config = read_yaml_config(settings.yaml_file)
app.state.config = config
return config
except ValidationError as e:
logger.error("Errors where found while reading configuration:")
for error in e.errors():
logger.error(f"{error['loc']} is {error['type']}")
sys.exit(1)
def setup_database(app, settings):
engine = create_engine(
settings.database_url, connect_args={"check_same_thread": False}
)
app.state.SessionLocal = sessionmaker(
autocommit=False, autoflush=False, bind=engine
)
app.state.engine = engine
models.Base.metadata.create_all(bind=engine)
app = get_application()