Spaces:
Sleeping
Sleeping
| import os | |
| from fastapi import FastAPI, Request | |
| from fastapi.responses import HTMLResponse, RedirectResponse | |
| from fastapi.staticfiles import StaticFiles | |
| from fastapi.templating import Jinja2Templates | |
| from starlette.middleware.sessions import SessionMiddleware | |
| from authlib.integrations.starlette_client import OAuth | |
| from math_server import mcp as math_mcp | |
| # ------------------------------- | |
| # Directories | |
| # ------------------------------- | |
| BASE_DIR = os.path.dirname(__file__) | |
| STATIC_DIR = os.path.join(BASE_DIR, "static") | |
| TEMPLATES_DIR = os.path.join(BASE_DIR, "templates") | |
| # ------------------------------- | |
| # App FastAPI | |
| # ------------------------------- | |
| app = FastAPI() | |
| # Session middleware nécessaire pour OAuth | |
| app.add_middleware(SessionMiddleware, secret_key=os.environ.get("SESSION_SECRET", "UN_SECRET_123")) | |
| # Static files | |
| app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static") | |
| templates = Jinja2Templates(directory=TEMPLATES_DIR) | |
| # ------------------------------- | |
| # Twitter OAuth configuration | |
| # ------------------------------- | |
| oauth = OAuth() | |
| oauth.register( | |
| name="twitter", | |
| client_id=os.environ.get("TWITTER_CLIENT_ID"), | |
| client_secret=os.environ.get("TWITTER_CLIENT_SECRET"), | |
| request_token_url=None, | |
| access_token_url="https://api.twitter.com/2/oauth2/token", | |
| authorize_url="https://twitter.com/i/oauth2/authorize", | |
| client_kwargs={"scope": "tweet.read users.read offline.access"}, | |
| ) | |
| # ------------------------------- | |
| # Endpoint racine | |
| # ------------------------------- | |
| async def index(request: Request): | |
| space_host = os.environ.get("SPACE_HOST") | |
| if space_host and space_host.strip(): | |
| base_url = space_host.strip().rstrip("/") | |
| else: | |
| base_url = f"{request.url.scheme}://{request.url.netloc}" | |
| user = request.session.get("user") | |
| return templates.TemplateResponse("index.html", {"request": request, "base_url": base_url, "user": user}) | |
| # ------------------------------- | |
| # Twitter OAuth endpoints | |
| # ------------------------------- | |
| async def login(request: Request): | |
| redirect_uri = request.url_for("auth_callback") | |
| return await oauth.twitter.authorize_redirect(request, redirect_uri) | |
| async def auth_callback(request: Request): | |
| token = await oauth.twitter.authorize_access_token(request) | |
| user_info = await oauth.twitter.parse_id_token(request, token) | |
| request.session["user"] = {"id": user_info.get("sub"), "username": user_info.get("name")} | |
| return RedirectResponse(url="/") | |
| async def logout(request: Request): | |
| request.session.pop("user", None) | |
| return RedirectResponse(url="/") | |
| # ------------------------------- | |
| # Endpoint MCP math | |
| # ------------------------------- | |
| app.mount("/math", math_mcp.http_app()) # juste le HTTP app, pas besoin de run() | |
| # ------------------------------- | |
| # Lancer le serveur | |
| # ------------------------------- | |
| PORT = int(os.environ.get("PORT", "10000")) | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=PORT) | |