File size: 3,106 Bytes
7ca901a
53bf046
7ca901a
53bf046
 
 
7ca901a
53bf046
7ca901a
 
53bf046
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7ca901a
53bf046
 
 
 
7ca901a
53bf046
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import os
import json
import gradio as gr
from fastapi import FastAPI, Header, HTTPException, Request
from fastapi.responses import JSONResponse
from gradio.routes import mount_gradio_app

# Import your existing Gradio app
from gradio_app import create_gradio_app

# ========= Configuration =========
PORT = int(os.environ.get("PORT", 7860))
MCP_BEARER = os.getenv("MCP_BEARER", "")  # définir dans Spaces > Settings > Variables and secrets

# ========= App FastAPI (parent) =========
api = FastAPI(title="MCP + Gradio on HF Spaces")

@api.get("/health")
def health():
    return {"ok": True}

def _check_auth(authorization: str | None):
    """Vérifie le header Authorization: Bearer <token> si MCP_BEARER est défini."""
    if not MCP_BEARER:
        return
    if not authorization or not authorization.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Missing or invalid Authorization header")
    token = authorization.split(" ", 1)[1]
    if token != MCP_BEARER:
        raise HTTPException(status_code=401, detail="Unauthorized")

# ========= Endpoint MCP (exemple minimal) =========
@api.post("/mcp")
async def mcp_endpoint(request: Request, authorization: str | None = Header(None)):
    _check_auth(authorization)
    try:
        payload = await request.json()
    except Exception:
        raise HTTPException(status_code=400, detail="Invalid JSON")

    # TODO: remplace ici par ta logique MCP réelle (dispatch, tools, resources, etc.)
    # Pour démarrer, on renvoie simplement le payload reçu.
    return JSONResponse({"status": "ok", "echo": payload})

# ========= UI Gradio =========
# Use your existing comprehensive agricultural analysis interface
demo = create_gradio_app()

# Monte Gradio sous la racine "/"
app = mount_gradio_app(api, demo, path="/")

# ========= Entrée (pour exécution locale éventuelle) =========
if __name__ == "__main__":
    # En local uniquement ; sur Spaces, le runner est géré par la plateforme.
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=PORT)

# ========= Tests curl (exemples en commentaires) =========
# Healthcheck (public, GET)
# curl -s https://<ORG>-<SPACE>.hf.space/health

# MCP sans auth (si MCP_BEARER non défini)
# curl -s -X POST https://<ORG>-<SPACE>.hf.space/mcp \
#   -H "Content-Type: application/json" \
#   -d '{"ping":"pong"}'

# MCP avec Bearer (si MCP_BEARER défini)
# curl -s -X POST https://<ORG>-<SPACE>.hf.space/mcp \
#   -H "Authorization: Bearer <TON_TOKEN>" \
#   -H "Content-Type: application/json" \
#   -d '{"ping":"pong"}'

# Test de l'UI Gradio
# curl -s https://<ORG>-<SPACE>.hf.space/

# Exemples de payloads MCP pour tester les fonctionnalités agricoles:
# curl -s -X POST https://<ORG>-<SPACE>.hf.space/mcp \
#   -H "Content-Type: application/json" \
#   -d '{"method": "analyze_weed_pressure", "params": {"years": [2020, 2021, 2022], "plots": ["P1", "P2"]}}'

# curl -s -X POST https://<ORG>-<SPACE>.hf.space/mcp \
#   -H "Content-Type: application/json" \
#   -d '{"method": "predict_future_pressure", "params": {"target_years": [2025, 2026], "max_ift": 1.0}}'