Files
han-app/VM2_services/codebase/services/message-safety/app/main.py
T

80 lines
2.5 KiB
Python

from __future__ import annotations
import asyncio
import uvicorn
from app.adapters import TrustedDnsResolver
from app.api import create_app
from app.config import ActiveConfig, validate_config
from app.db import engine_and_sessions
from app.file_pipeline import DependencyFailure, KeslSocketScanner
from app.repository import Repository
from app.service import SafetyService
from app.settings import BootstrapSettings, EmergencyMode
from app.telemetry import init_telemetry, instrument_fastapi, shutdown_telemetry
async def build_runtime() -> tuple[object, object]:
settings = BootstrapSettings()
assert settings.database_url and settings.service_token
engine, sessions = engine_and_sessions(settings.database_url.get_secret_value())
repository = Repository(sessions)
row = await repository.active_config()
rules, detector, digest = validate_config(row.config, settings.artifacts_dir)
if digest != row.config_sha256:
raise RuntimeError("active config hash mismatch")
config = ActiveConfig(row.version, row.config, rules, detector)
mode = EmergencyMode.from_file(settings.mode_file)
resolver = TrustedDnsResolver(
[item.strip() for item in settings.dns_resolvers.split(",") if item.strip()]
)
antivirus = KeslSocketScanner(settings.antivirus_socket)
if mode.mock:
signatures_version = "unavailable"
files_ready = False
else:
try:
status = await antivirus.status()
signatures_version = status.signatures_version
files_ready = True
except DependencyFailure:
signatures_version = "unavailable"
files_ready = False
service = SafetyService(
repository,
config,
mode,
resolver,
files_ready=files_ready,
signatures_version=signatures_version,
antivirus=antivirus,
)
app = create_app(service, settings.service_token.get_secret_value())
instrument_fastapi(app)
return app, engine
async def serve() -> None:
settings = BootstrapSettings()
init_telemetry("api")
engine = None
try:
app, engine = await build_runtime()
server = uvicorn.Server(
uvicorn.Config(app, host=settings.host, port=settings.port, proxy_headers=False)
)
await server.serve()
finally:
if engine is not None:
await engine.dispose()
shutdown_telemetry()
def run() -> None:
asyncio.run(serve())
if __name__ == "__main__":
run()