Spaces:
Sleeping
Sleeping
File size: 4,946 Bytes
47e1fe8 fefcf20 cb8383e ad334a5 3144b93 8e66916 47e1fe8 e2aca56 47e1fe8 ad334a5 47e1fe8 ad334a5 8e66916 fefcf20 8e66916 ad334a5 c9212dc 8e66916 3144b93 8e66916 3144b93 8e66916 3144b93 8e66916 47e1fe8 cb8383e ad334a5 cb8383e 8e66916 a6684e6 99c2056 8731f06 8e66916 8731f06 ad334a5 8731f06 ad334a5 e3d64de ad334a5 0464135 c9212dc 0464135 ad334a5 e3d64de 8e66916 8731f06 8e66916 e3d64de 8e66916 9244fa9 8e66916 8731f06 8e66916 8731f06 47e1fe8 |
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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
from fastapi import FastAPI, Request, HTTPException
import os
import requests
from typing import Dict, Any
from openai import OpenAI
import httpx
import time
app = FastAPI()
# Configuration de l'API d'inférence NVIDIA
BOT_USERNAME = "@DiscussionBot"
NVIDIA_API_URL = "https://integrate.api.nvidia.com/v1"
NVIDIA_API_KEY = os.getenv("NVIDIA_API_KEY")
MODEL = "mistralai/mixtral-8x7b-instruct-v0.1"
# Vérification de la clé API NVIDIA
if not NVIDIA_API_KEY:
raise ValueError("NVIDIA_API_KEY environment variable is not set.")
# Vérification du jeton Hugging Face
HF_TOKEN = os.getenv("HF_TOKEN")
if not HF_TOKEN:
raise ValueError("HF_TOKEN environment variable is not set.")
# Initialisation du client NVIDIA
try:
client = OpenAI(
base_url=NVIDIA_API_URL,
api_key=NVIDIA_API_KEY,
http_client=httpx.Client(proxies=None, timeout=30.0)
)
except Exception as e:
raise ValueError(f"Failed to initialize NVIDIA API client: {str(e)}")
@app.get("/")
async def root(request: Request) -> Dict[str, Any]:
"""
Gère les requêtes GET et renvoie une réponse JSON simple.
"""
return {
"method": request.method,
"host": request.headers.get("host", "unknown"),
"user_agent": request.headers.get("user-agent", "unknown"),
"query_test": request.query_params.get("test", None),
"message": "Webhook server is running. Use POST to interact with the bot."
}
@app.post("/")
async def webhook(request: Request) -> Dict[str, Any]:
"""
Gère les requêtes POST des Webhooks pour traiter les commentaires mentionnant le bot.
"""
try:
if request.headers.get("X-Webhook-Secret") != os.getenv("WEBHOOK_SECRET"):
raise HTTPException(status_code=400, detail="Secret incorrect")
data = await request.json()
event = data.get("event", {})
if (
event.get("action") == "create"
and event.get("scope") == "discussion.comment"
and BOT_USERNAME in data.get("comment", {}).get("content", "")
):
# Préparation du prompt pour l'API NVIDIA
messages = [
{
"role": "user",
"content": f"Faites comme si vous étiez un robot qui répond aux discussions sur l'apprentissage automatique et répondez au commentaire suivant :\n{data['comment']['content']}"
}
]
# Requête à l'API NVIDIA
try:
completion = client.chat.completions.create(
model=MODEL,
messages=messages,
temperature=0.5,
top_p=1,
max_tokens=100,
stream=True
)
continuation_text = ""
for chunk in completion:
if chunk.choices[0].delta.content is not None:
continuation_text += chunk.choices[0].delta.content
continuation_text = continuation_text.strip()
if not continuation_text:
raise ValueError("No text generated by NVIDIA API")
except Exception as e:
raise HTTPException(status_code=500, detail=f"Inference failed: {str(e)}")
# Publication du commentaire avec gestion des nouvelles tentatives
comment_url = data["discussion"]["url"]["api"] + "/comment"
for attempt in range(5): # 5 tentatives maximum
try:
comment_response = requests.post(
comment_url,
headers={
"Authorization": f"Bearer {HF_TOKEN}",
"Content-Type": "application/json",
},
json={"comment": continuation_text},
)
comment_response.raise_for_status()
# Vérifier si la réponse contient "newMessage" (succès implicite)
if comment_response.json().get("newMessage"):
return {"success": True}
return {"success": True}
except requests.exceptions.HTTPError as e:
if "429" in str(e) or "rate-limited" in str(e):
time.sleep((2 ** attempt) * 10) # Backoff exponentiel plus long
continue
raise HTTPException(status_code=500, detail=f"Failed to post comment: {str(e)}")
raise HTTPException(status_code=429, detail="Rate limit exceeded after retries")
return {"success": False}
except HTTPException as he:
raise he
except Exception as e:
raise HTTPException(status_code=500, detail=f"Unexpected error: {str(e)}")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860) |