Spaces:
Sleeping
Sleeping
File size: 3,138 Bytes
692e2cd 57e07be ca4b3c5 57e07be ca4b3c5 57e07be ca4b3c5 57e07be ca4b3c5 57e07be ca4b3c5 57e07be ca4b3c5 57e07be ca4b3c5 57e07be ca4b3c5 57e07be ca4b3c5 57e07be ca4b3c5 57e07be ca4b3c5 57e07be ca4b3c5 57e07be 7a83f12 57e07be 7a83f12 57e07be 0ba0284 7a83f12 692e2cd 57e07be | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | 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
# -------------------------------
@app.get("/", response_class=HTMLResponse)
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
# -------------------------------
@app.get("/auth/twitter/login")
async def login(request: Request):
redirect_uri = request.url_for("auth_callback")
return await oauth.twitter.authorize_redirect(request, redirect_uri)
@app.get("/auth/twitter/callback")
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="/")
@app.get("/auth/logout")
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)
|