QuentinL52 commited on
Commit
301d334
·
verified ·
1 Parent(s): 4dda4d2

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +20 -77
main.py CHANGED
@@ -1,32 +1,19 @@
1
- import logging
2
- import sys
3
  import os
4
- import json
5
- import tempfile
6
- from datetime import datetime
7
-
8
- from fastapi import FastAPI, Request, HTTPException, UploadFile, File, BackgroundTasks, Query
9
  from fastapi.responses import JSONResponse
10
- from fastapi.concurrency import run_in_threadpool
11
  from fastapi.middleware.cors import CORSMiddleware
12
- from pydantic import BaseModel, Field
13
- from typing import List, Dict, Any, Optional
14
- from bson import ObjectId
15
 
16
- from src.models import load_all_models
17
- from src.services.cv_service import CVParsingService
18
- from src.services.analysis_service import AnalysisService
19
- from services.graph_service import GraphInterviewProcessor
20
 
21
  logging.basicConfig(level=logging.INFO)
22
  logger = logging.getLogger(__name__)
23
 
24
- os.makedirs('/tmp/feedbacks', exist_ok=True)
25
-
26
  app = FastAPI(
27
- title="AIrh Interview Assistant",
28
- description="API pour l'analyse de CV et la simulation d'entretiens d'embauche avec analyse asynchrone.",
29
- version="2.0.0",
30
  docs_url="/docs",
31
  redoc_url="/redoc"
32
  )
@@ -39,88 +26,44 @@ app.add_middleware(
39
  allow_headers=["*"],
40
  )
41
 
42
- # --- Initialisation des services ---
43
- logger.info("Chargement des modèles et initialisation des services...")
44
- models = load_all_models()
45
- cv_service = CVParsingService(models)
46
- logger.info("Services initialisés.")
47
-
48
-
49
- # --- Définition des modèles Pydantic ---
50
- class Feedback(BaseModel):
51
- status: str
52
- feedback_data: Optional[Dict[str, Any]] = None
53
-
54
  class HealthCheck(BaseModel):
55
  status: str = "ok"
56
 
57
- # --- Endpoint de santé ---
58
  @app.get("/", response_model=HealthCheck, tags=["Status"])
59
  async def health_check():
60
  return HealthCheck()
61
 
62
- # --- Endpoint principal pour la simulation d'entretien ---
63
  @app.post("/simulate-interview/")
64
  async def simulate_interview(request: Request):
65
  """
66
- Ce endpoint reçoit les données de l'entretien, instancie le processeur de graphe
67
- et lance la conversation.
68
  """
69
- # CORRECTION : Récupérer l'instance du logger pour garantir sa disponibilité dans le scope de la fonction.
70
  logger = logging.getLogger(__name__)
71
  try:
72
  payload = await request.json()
73
-
74
  if not all(k in payload for k in ["user_id", "job_offer_id", "cv_document", "job_offer"]):
75
- raise HTTPException(status_code=400, detail="Données manquantes dans le payload (user_id, job_offer_id, cv_document, job_offer).")
76
-
77
- logger.info(f"Début de la simulation pour l'utilisateur : {payload['user_id']}")
78
-
79
  processor = GraphInterviewProcessor(payload)
80
  result = processor.invoke(payload.get("messages", []))
81
-
82
  return JSONResponse(content=result)
83
 
84
  except ValueError as ve:
85
- logger.error(f"Erreur de validation des données : {ve}", exc_info=True)
86
  return JSONResponse(content={"error": str(ve)}, status_code=400)
87
  except Exception as e:
88
- logger.error(f"Erreur interne dans le endpoint simulate-interview: {e}", exc_info=True)
89
  return JSONResponse(
90
- content={"error": "Une erreur interne est survenue sur le serveur de l'assistant."},
91
  status_code=500
92
  )
93
 
94
- # --- Endpoint pour l'analyse de CV ---
95
- @app.post("/parse-cv/", tags=["CV Parsing"])
96
- async def parse_cv(
97
- file: UploadFile = File(...),
98
- user_id: str = Query(None, description="ID de l'utilisateur pour lier le CV")
99
- ):
100
- """
101
- Analyse un fichier CV (PDF) et le stocke automatiquement dans MongoDB.
102
- """
103
- if file.content_type != "application/pdf":
104
- raise HTTPException(status_code=400, detail="Fichier PDF requis")
105
-
106
- contents = await file.read()
107
-
108
- with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp:
109
- tmp.write(contents)
110
- tmp_path = tmp.name
111
-
112
- try:
113
- result = await run_in_threadpool(cv_service.parse_cv, tmp_path, user_id)
114
- finally:
115
- if os.path.exists(tmp_path):
116
- os.remove(tmp_path)
117
-
118
- if not result:
119
- raise HTTPException(status_code=500, detail="Échec de l'extraction des données du CV.")
120
-
121
- return result
122
-
123
- # --- Démarrage de l'application (pour un test local) ---
124
  if __name__ == "__main__":
125
  import uvicorn
126
- uvicorn.run(app, host="0.0.0.0", port=8000)
 
 
 
 
1
  import os
2
+ import logging
3
+ from fastapi import FastAPI, Request, HTTPException
 
 
 
4
  from fastapi.responses import JSONResponse
 
5
  from fastapi.middleware.cors import CORSMiddleware
6
+ from pydantic import BaseModel
 
 
7
 
8
+ from src.services.graph_service import GraphInterviewProcessor
 
 
 
9
 
10
  logging.basicConfig(level=logging.INFO)
11
  logger = logging.getLogger(__name__)
12
 
 
 
13
  app = FastAPI(
14
+ title="Interview Simulation API",
15
+ description="API for interview simulations.",
16
+ version="1.0.0",
17
  docs_url="/docs",
18
  redoc_url="/redoc"
19
  )
 
26
  allow_headers=["*"],
27
  )
28
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  class HealthCheck(BaseModel):
30
  status: str = "ok"
31
 
 
32
  @app.get("/", response_model=HealthCheck, tags=["Status"])
33
  async def health_check():
34
  return HealthCheck()
35
 
 
36
  @app.post("/simulate-interview/")
37
  async def simulate_interview(request: Request):
38
  """
39
+ This endpoint receives the interview data, instantiates the graph processor
40
+ and starts the conversation.
41
  """
 
42
  logger = logging.getLogger(__name__)
43
  try:
44
  payload = await request.json()
45
+
46
  if not all(k in payload for k in ["user_id", "job_offer_id", "cv_document", "job_offer"]):
47
+ raise HTTPException(status_code=400, detail="Missing data in payload (user_id, job_offer_id, cv_document, job_offer).")
48
+
49
+ logger.info(f"Starting simulation for user: {payload['user_id']}")
50
+
51
  processor = GraphInterviewProcessor(payload)
52
  result = processor.invoke(payload.get("messages", []))
53
+
54
  return JSONResponse(content=result)
55
 
56
  except ValueError as ve:
57
+ logger.error(f"Data validation error: {ve}", exc_info=True)
58
  return JSONResponse(content={"error": str(ve)}, status_code=400)
59
  except Exception as e:
60
+ logger.error(f"Internal error in simulate-interview endpoint: {e}", exc_info=True)
61
  return JSONResponse(
62
+ content={"error": "An internal error occurred on the assistant's server."},
63
  status_code=500
64
  )
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  if __name__ == "__main__":
67
  import uvicorn
68
+ port = int(os.getenv("PORT", 8002)) # Use PORT environment variable, default to 8002
69
+ uvicorn.run(app, host="0.0.0.0", port=port)