Update main.py
Browse files
main.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
| 1 |
import os
|
| 2 |
from fastapi import FastAPI, UploadFile, File, HTTPException, Form
|
|
|
|
|
|
|
| 3 |
from fastapi.middleware.cors import CORSMiddleware
|
| 4 |
from pydantic import BaseModel
|
| 5 |
from groq import Groq
|
|
@@ -7,7 +9,6 @@ import base64
|
|
| 7 |
|
| 8 |
app = FastAPI(title="BSTP-Cameroun-AI-Engine")
|
| 9 |
|
| 10 |
-
# Configuration CORS pour permettre à l'application Frontend de communiquer librement avec l'API
|
| 11 |
app.add_middleware(
|
| 12 |
CORSMiddleware,
|
| 13 |
allow_origins=["*"],
|
|
@@ -83,7 +84,13 @@ FULL_SYSTEM_PROMPT = SYSTEM_PROMPT + "\n\nOFFICIAL BSTP REFERENCE CONTEXT FROM D
|
|
| 83 |
|
| 84 |
class TextRequest(BaseModel):
|
| 85 |
text: str
|
| 86 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
@app.get("/")
|
| 88 |
def read_root():
|
| 89 |
return {
|
|
@@ -207,4 +214,57 @@ async def audit_document(file: UploadFile = File(...), document_type: str = Form
|
|
| 207 |
return json.loads(response.choices[0].message.content)
|
| 208 |
|
| 209 |
except Exception as e:
|
| 210 |
-
raise HTTPException(status_code=500, detail=f"Erreur lors de l'analyse OCR/Vision par Groq : {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import os
|
| 2 |
from fastapi import FastAPI, UploadFile, File, HTTPException, Form
|
| 3 |
+
from pydantic import BaseModel, Field
|
| 4 |
+
from typing import Dict, Optional
|
| 5 |
from fastapi.middleware.cors import CORSMiddleware
|
| 6 |
from pydantic import BaseModel
|
| 7 |
from groq import Groq
|
|
|
|
| 9 |
|
| 10 |
app = FastAPI(title="BSTP-Cameroun-AI-Engine")
|
| 11 |
|
|
|
|
| 12 |
app.add_middleware(
|
| 13 |
CORSMiddleware,
|
| 14 |
allow_origins=["*"],
|
|
|
|
| 84 |
|
| 85 |
class TextRequest(BaseModel):
|
| 86 |
text: str
|
| 87 |
+
class BenchmarkRequest(BaseModel):
|
| 88 |
+
company_name: str
|
| 89 |
+
sector: str # ex: "Agro-industrie", "BTP", "Hydrocarbures"
|
| 90 |
+
sme_scores: Dict[str, float]
|
| 91 |
+
sector_average_scores: Optional[Dict[str, float]] = None
|
| 92 |
+
total_companies_in_sector: Optional[int] = None
|
| 93 |
+
current_rank_in_sector: Optional[int] = None
|
| 94 |
@app.get("/")
|
| 95 |
def read_root():
|
| 96 |
return {
|
|
|
|
| 214 |
return json.loads(response.choices[0].message.content)
|
| 215 |
|
| 216 |
except Exception as e:
|
| 217 |
+
raise HTTPException(status_code=500, detail=f"Erreur lors de l'analyse OCR/Vision par Groq : {str(e)}")
|
| 218 |
+
@app.post("/api/benchmarking")
|
| 219 |
+
async def get_benchmarking_analysis(request: BenchmarkRequest):
|
| 220 |
+
if not groq_client:
|
| 221 |
+
raise HTTPException(status_code=500, detail="Le moteur d'IA Groq n'est pas configuré.")
|
| 222 |
+
|
| 223 |
+
# CAS 1 : On n'a pas encore de données dans l'application (Démarrage à vide)
|
| 224 |
+
if request.sector_average_scores is None:
|
| 225 |
+
benchmark_prompt = (
|
| 226 |
+
f"You are a senior industrial consultant specializing in Sub-Saharan African economies.\n"
|
| 227 |
+
f"The BSTP Cameroon database is currently in its deployment phase and lacks local aggregate data.\n"
|
| 228 |
+
f"Analyze this Cameroonian SME based on current international standards (UNIDO, ISO, OHADA) "
|
| 229 |
+
f"and typical economic data available on the internet for the Central African region:\n\n"
|
| 230 |
+
f"- Company Name: {request.company_name}\n"
|
| 231 |
+
f"- Sector: {request.sector}\n"
|
| 232 |
+
f"- SME Actual Scores (out of 10): {request.sme_scores}\n\n"
|
| 233 |
+
f"YOUR TASK:\n"
|
| 234 |
+
f"1. Based on market knowledge, general benchmarks for the '{request.sector}' sector in Cameroon, "
|
| 235 |
+
f"and UNIDO compliance rules, establish a theoretical baseline for each of their 6 axes.\n"
|
| 236 |
+
f"2. Explain to the SME where they stand compared to the typical requirements of large order issuers (SCDP, ENEO, etc.).\n"
|
| 237 |
+
f"3. Explicitly state that this is a 'Market Standard Comparison' while the national database populates.\n\n"
|
| 238 |
+
f"Reply in French or English depending on the query. Keep it formal and highly professional."
|
| 239 |
+
)
|
| 240 |
+
|
| 241 |
+
# CAS 2 : On a des vraies données en BDD
|
| 242 |
+
else:
|
| 243 |
+
benchmark_prompt = (
|
| 244 |
+
f"Perform a professional benchmarking analysis based on actual database statistics:\n"
|
| 245 |
+
f"- Company Name: {request.company_name}\n"
|
| 246 |
+
f"- Sector: {request.sector}\n"
|
| 247 |
+
f"- Current Rank: {request.current_rank_in_sector} out of {request.total_companies_in_sector}\n"
|
| 248 |
+
f"- SME Scores: {request.sme_scores}\n"
|
| 249 |
+
f"- Database Averages: {request.sector_average_scores}"
|
| 250 |
+
)
|
| 251 |
+
|
| 252 |
+
try:
|
| 253 |
+
completion = groq_client.chat.completions.create(
|
| 254 |
+
model="llama-3.3-70b-versatile",
|
| 255 |
+
messages=[
|
| 256 |
+
{"role": "system", "content": FULL_SYSTEM_PROMPT},
|
| 257 |
+
{"role": "user", "content": benchmark_prompt}
|
| 258 |
+
],
|
| 259 |
+
temperature=0.3,
|
| 260 |
+
max_tokens=1500
|
| 261 |
+
)
|
| 262 |
+
|
| 263 |
+
return {
|
| 264 |
+
"company_name": request.company_name,
|
| 265 |
+
"sector": request.sector,
|
| 266 |
+
"mode": "Market Standards (Web/UNIDO)" if request.sector_average_scores is None else "Database Actuals",
|
| 267 |
+
"benchmarking_report": completion.choices[0].message.content
|
| 268 |
+
}
|
| 269 |
+
except Exception as e:
|
| 270 |
+
raise HTTPException(status_code=500, detail=f"Erreur lors du benchmarking : {str(e)}")
|