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): response = await process(req.text) return {"response": response} @app.get("/status") async def status(): await wireclaw_core.refresh_position(wireclaw_core.drone) async for bat in wireclaw_core.drone.telemetry.battery(): raw = bat.remaining_percent pct = abs(raw) * 100 if abs(raw) <= 1 else abs(raw) break async for fm in wireclaw_core.drone.telemetry.flight_mode(): mode = str(fm) break 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(pct, 1), "mode": mode, "armed": wireclaw_core.drone_armed, } @app.get("/") async def index(): return HTMLResponse(HTML) HTML = """