import asyncio from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.responses import HTMLResponse, JSONResponse from pydantic import BaseModel import wireclaw_core @asynccontextmanager async def lifespan(app: FastAPI): await wireclaw_core.init() yield app = FastAPI(lifespan=lifespan) async def process(text: str) -> str: """Point d'entrée générique : texte libre → commande interprétée → exécutée.""" cmd = await wireclaw_core.interpret_command(text) return await wireclaw_core.execute_command(wireclaw_core.drone, cmd) class CommandRequest(BaseModel): text: str @app.post("/command") async def command(req: CommandRequest): try: response = await process(req.text) return {"response": response} except Exception as e: return JSONResponse(status_code=500, content={"response": f"Erreur : {e}"}) @app.get("/status") async def status(): # Lecture pure depuis les caches mis à jour par les tâches de fond — # aucun appel bloquant, réponse instantanée return { "lat": wireclaw_core.current_pos["lat"], "lon": wireclaw_core.current_pos["lon"], "alt": round(wireclaw_core.current_pos["alt"], 2), "abs_alt": round(wireclaw_core.current_pos["abs_alt"], 2), "battery": round(wireclaw_core.telemetry_cache["battery"], 1), "mode": wireclaw_core.telemetry_cache["mode"], "armed": wireclaw_core.drone_armed, } @app.get("/") async def index(): return HTMLResponse(HTML) HTML = """