EnzGamers commited on
Commit
49ce3ab
·
verified ·
1 Parent(s): 2b674d2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -92
app.py CHANGED
@@ -1,104 +1,53 @@
1
  from fastapi import FastAPI, Request
2
- from pydantic import BaseModel, Extra
3
- import torch
4
- from transformers import AutoModelForCausalLM, AutoTokenizer
5
- import time
6
- import uuid
7
- from typing import Optional, List, Any
8
 
9
- # --- Configuration ---
10
- MODEL_ID = "deepseek-ai/deepseek-coder-1.3b-instruct"
11
- DEVICE = "cpu"
12
-
13
- # --- Chargement du modèle et du tokenizer ---
14
- print(f"Début du chargement du modèle : {MODEL_ID}")
15
- model = AutoModelForCausalLM.from_pretrained(
16
- MODEL_ID,
17
- torch_dtype=torch.bfloat16,
18
- device_map=DEVICE
19
- )
20
- tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
21
- print("Modèle et tokenizer chargés avec succès sur le CPU.")
22
-
23
- # --- Création de l'application API ---
24
  app = FastAPI()
25
 
26
- # --- Modèles de données pour la compatibilité OpenAI ---
27
- class ChatMessage(BaseModel):
28
- role: str
29
- content: str
30
-
31
- class ChatCompletionRequest(BaseModel):
32
- # On rend presque tout optionnel pour maximiser la compatibilité
33
- model: Optional[str] = None
34
- messages: Optional[List[ChatMessage]] = None
35
- prompt: Optional[str] = None # Certaines extensions envoient "prompt" au lieu de "messages"
36
- max_tokens: Optional[int] = 250
37
-
38
- # LA MODIFICATION LA PLUS IMPORTANTE : Ignorer les champs inconnus
39
- class Config:
40
- extra = Extra.ignore
41
-
42
- class ChatCompletionResponseChoice(BaseModel):
43
- index: int = 0
44
- message: ChatMessage
45
- finish_reason: str = "stop"
46
-
47
- class ChatCompletionResponse(BaseModel):
48
- id: str
49
- object: str = "chat.completion"
50
- created: int
51
- model: str
52
- choices: List[ChatCompletionResponseChoice]
53
-
54
- class ModelData(BaseModel):
55
- id: str
56
- object: str = "model"
57
- created: int = int(time.time())
58
- owned_by: str = "user"
59
 
60
- class ModelList(BaseModel):
61
- object: str = "list"
62
- data: List[ModelData]
63
-
64
- # --- Définition des API ---
65
-
66
- @app.get("/models", response_model=ModelList)
67
  async def list_models():
68
- """Endpoint pour lister les modèles disponibles."""
69
- return ModelList(data=[ModelData(id=MODEL_ID)])
70
-
71
- @app.post("/chat/completions", response_model=ChatCompletionResponse)
72
- async def create_chat_completion(request: ChatCompletionRequest):
73
- """Endpoint principal pour la génération de texte."""
74
- user_prompt = ""
75
- # On cherche le prompt de l'utilisateur de plusieurs manières possibles
76
- if request.prompt:
77
- user_prompt = request.prompt
78
- elif request.messages and request.messages[-1].role == "user":
79
- user_prompt = request.messages[-1].content
80
 
81
- if not user_prompt:
82
- return {"error": "Could not find a valid prompt in the request."}
83
-
84
- messages_for_model = [{'role': 'user', 'content': user_prompt}]
85
- inputs = tokenizer.apply_chat_template(messages_for_model, add_generation_prompt=True, return_tensors="pt").to(DEVICE)
86
 
87
- outputs = model.generate(inputs, max_new_tokens=request.max_tokens, do_sample=True, temperature=0.2, top_k=50, top_p=0.95, num_return_sequences=1, eos_token_id=tokenizer.eos_token_id)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
- response_text = tokenizer.decode(outputs[0][len(inputs[0]):], skip_special_tokens=True)
90
-
91
- response_message = ChatMessage(role="assistant", content=response_text)
92
- choice = ChatCompletionResponseChoice(message=response_message)
93
- completion_response = ChatCompletionResponse(
94
- id=f"chatcmpl-{uuid.uuid4()}",
95
- created=int(time.time()),
96
- model=MODEL_ID,
97
- choices=[choice]
98
- )
99
-
100
- return completion_response
101
 
102
  @app.get("/")
103
  def root():
104
- return {"status": "API compatible OpenAI en ligne", "model_id": MODEL_ID}
 
1
  from fastapi import FastAPI, Request
2
+ from fastapi.responses import JSONResponse
3
+ import json
 
 
 
 
4
 
5
+ # --- Création de l'application API de diagnostic ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  app = FastAPI()
7
 
8
+ # --- Définition des API de diagnostic ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
+ @app.get("/models")
 
 
 
 
 
 
11
  async def list_models():
12
+ """Répond à la requête GET /models pour que l'extension soit satisfaite."""
13
+ print("--- REQUETE RECUE SUR /models ---")
14
+ return {"object": "list", "data": [{"id": "deepseek-ai/deepseek-coder-1.3b-instruct", "object": "model"}]}
15
+
16
+ @app.post("/chat/completions")
17
+ async def debug_chat_completion(request: Request):
18
+ """
19
+ Endpoint qui ne fait qu'une seule chose :
20
+ afficher le contenu exact de la requête envoyée par VS Code.
21
+ """
22
+ print("\n\n" + "="*50)
23
+ print("=== REQUETE POST RECUE SUR /chat/completions ===")
24
 
25
+ # On affiche les headers de la requête
26
+ print("\n--- HEADERS ---")
27
+ for name, value in request.headers.items():
28
+ print(f"{name}: {value}")
 
29
 
30
+ # On essaie de lire et d'afficher le corps (body) de la requête
31
+ try:
32
+ body = await request.json()
33
+ print("\n--- BODY (JSON) ---")
34
+ # On utilise json.dumps pour un affichage propre
35
+ print(json.dumps(body, indent=2))
36
+ except Exception as e:
37
+ print(f"\n--- ERREUR LORS DE LA LECTURE DU BODY ---")
38
+ print(f"L'erreur est : {e}")
39
+ # On essaie de lire le corps comme du texte brut si le JSON échoue
40
+ body_raw = await request.body()
41
+ print("\n--- BODY (BRUT) ---")
42
+ print(body_raw.decode('utf-8', errors='ignore'))
43
+
44
+ print("="*50 + "\n\n")
45
 
46
+ # On renvoie une erreur 422 volontairement pour pouvoir retenter facilement.
47
+ # Le but n'est pas que ça marche, mais de voir les logs.
48
+ error_message = {"error": "Mode diagnostic actif. Vérifiez les logs du Space."}
49
+ return JSONResponse(status_code=422, content=error_message)
 
 
 
 
 
 
 
 
50
 
51
  @app.get("/")
52
  def root():
53
+ return {"status": "API en mode diagnostic. Vérifiez les logs."}