Files
jardin/backend/app/main.py

98 lines
2.8 KiB
Python

import asyncio
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.config import CORS_ORIGINS, ENABLE_BOOTSTRAP, ENABLE_SCHEDULER, UPLOAD_DIR
from app.database import create_db_and_tables
@asynccontextmanager
async def lifespan(app: FastAPI):
os.makedirs(UPLOAD_DIR, exist_ok=True)
try:
os.makedirs("/data/skyfield", exist_ok=True)
except OSError:
pass
if ENABLE_BOOTSTRAP:
import app.models # noqa — enregistre tous les modèles avant create_all
from app.migrate import run_migrations
run_migrations()
create_db_and_tables()
from app.seed import run_seed
run_seed()
if ENABLE_SCHEDULER:
from app.services.scheduler import setup_scheduler, backfill_station_missing_dates
setup_scheduler()
# Backfill des dates manquantes en arrière-plan (ne bloque pas le démarrage)
loop = asyncio.get_running_loop()
loop.run_in_executor(None, backfill_station_missing_dates)
yield
if ENABLE_BOOTSTRAP and ENABLE_SCHEDULER:
from app.services.scheduler import scheduler
scheduler.shutdown(wait=False)
app = FastAPI(
title="Jardin API",
lifespan=lifespan,
redoc_js_url="https://cdn.jsdelivr.net/npm/redoc@2.1.3/bundles/redoc.standalone.js"
)
app.add_middleware(
CORSMiddleware,
allow_origins=CORS_ORIGINS,
allow_methods=["*"],
allow_headers=["*"],
)
from app.routers import ( # noqa
gardens,
plants,
plantings,
tasks,
settings,
media,
tools,
dictons,
saints,
astuces,
recoltes,
lunar,
meteo,
identify,
achats,
fabrications,
)
app.include_router(gardens.router, prefix="/api")
app.include_router(plants.router, prefix="/api")
app.include_router(plantings.router, prefix="/api")
app.include_router(tasks.router, prefix="/api")
app.include_router(settings.router, prefix="/api")
app.include_router(media.router, prefix="/api")
app.include_router(tools.router, prefix="/api")
app.include_router(dictons.router, prefix="/api")
app.include_router(saints.router, prefix="/api")
app.include_router(astuces.router, prefix="/api")
app.include_router(recoltes.router, prefix="/api")
app.include_router(lunar.router, prefix="/api")
app.include_router(meteo.router, prefix="/api")
app.include_router(identify.router, prefix="/api")
app.include_router(achats.router, prefix="/api")
app.include_router(fabrications.router, prefix="/api")
@app.get("/api/health")
def health():
return {"status": "ok"}
# Monter uploads seulement si le dossier existe
from fastapi.staticfiles import StaticFiles # noqa
if os.path.isdir(UPLOAD_DIR):
app.mount("/uploads", StaticFiles(directory=UPLOAD_DIR, html=False), name="uploads")