BilalBill commited on
Commit
7be4104
·
1 Parent(s): b0bc3af

fin du bot

Browse files
__pycache__/main.cpython-312.pyc ADDED
Binary file (6.8 kB). View file
 
agents/__init__.py DELETED
File without changes
agents/emergency_agent.py DELETED
File without changes
agents/main_agent.py DELETED
File without changes
agents/pharmacy_agent.py DELETED
@@ -1,56 +0,0 @@
1
- from langchain.agents import create_agent
2
- from langchain_groq import ChatGroq
3
- from langchain.tools import tool
4
- from langgraph.checkpoint.memory import InMemorySaver
5
- from langchain.messages import HumanMessage
6
-
7
- from dotenv import load_dotenv
8
- from pathlib import Path
9
-
10
- import sys
11
- import os
12
-
13
- ROOT_DIR = Path(__file__).resolve().parent.parent
14
- sys.path.append(str(ROOT_DIR))
15
- load_dotenv()
16
-
17
- from tools.pharma_tools import get_nearly
18
- from src.prompts import pharmacy_prompt
19
-
20
- def pharmacy_agent():
21
-
22
- api_key = os.environ.get('GROQ_API_KEY')
23
- llm = ChatGroq(
24
- model="openai/gpt-oss-120b",
25
- api_key=api_key,
26
- temperature=0,
27
- )
28
-
29
- pha_agent = create_agent(
30
- model = llm,
31
- tools = [get_nearly],
32
- system_prompt = pharmacy_prompt,
33
- checkpointer = InMemorySaver(),
34
- )
35
- return pha_agent
36
-
37
- # while True:
38
- # q = input("\nUrgence : ")
39
- # config = {"configurable": {"thread_id": "1"}}
40
-
41
- # if q.lower() == 'q':
42
- # break
43
- # q = HumanMessage(content=q)
44
- # try:
45
- # result = pha_agent.invoke({"messages": [q]}, config=config)
46
- # print(result['messages'][-1].content)
47
- # except Exception as e:
48
- # print(f"[BUG] l'agent n'a pas demarer !!")
49
- # print(f"Erreur : {e}")
50
-
51
- # if __name__ == '__main__':
52
- # pharmacy_agent()
53
-
54
-
55
-
56
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
api.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from pydantic import BaseModel
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ from typing import Any
5
+ from tools.transcription import transcribe_audio
6
+ from fastapi import File, UploadFile, Form
7
+ import os
8
+ import shutil
9
+ import uvicorn
10
+
11
+ # On importe graphe LangGraph depuis main.py
12
+ from main import app as langgraph_app
13
+
14
+ # Initialisation de l'API
15
+ app = FastAPI(
16
+ title="Nova Health API",
17
+ description="API d'orientation médicale propulsée par l'IA"
18
+ )
19
+
20
+ # --- CONFIGURATION CORS ---
21
+ app.add_middleware(
22
+ CORSMiddleware,
23
+ allow_origins=["*"],
24
+ allow_credentials=True,
25
+ allow_methods=["*"],
26
+ allow_headers=["*"],
27
+ )
28
+
29
+ @app.get("/")
30
+ async def accueil():
31
+ """Route d'accueil simple pour vérifier que l'API tourne."""
32
+ return {
33
+ "nom_projet": "Nova Health API",
34
+ "statut": "En ligne ",
35
+ "message": "Bienvenue ! Le système d'orientation médicale IA est opérationnel.",
36
+ "documentation": "Allez sur /docs pour tester l'API avec Swagger UI."
37
+ }
38
+
39
+ # --- MODÈLES DE DONNÉES (JSON) ---
40
+
41
+ # Ce que le frontend doit t'envoyer
42
+ class ChatRequest(BaseModel):
43
+ user_message: str
44
+ user_lat: float
45
+ user_lon: float
46
+
47
+ # front
48
+ class ChatResponse(BaseModel):
49
+ intention: str
50
+ mot_cle: str
51
+ reponse_texte: Any
52
+
53
+ # --- LA ROUTE DE L'API ---
54
+
55
+ @app.post("/api/chat", response_model=ChatResponse)
56
+ async def chat_endpoint(request: ChatRequest):
57
+ """
58
+ Reçoit le message et les coordonnées GPS du patient,
59
+ et renvoie l'orientation médicale formatée en JSON.
60
+
61
+ """
62
+ try:
63
+ # On prépare les données pour ton routeur LangGraph
64
+ inputs = {
65
+ "user_message": request.user_message,
66
+ "user_lat": request.user_lat,
67
+ "user_lon": request.user_lon
68
+ }
69
+
70
+ # On fait réfléchir l'IA
71
+ result = langgraph_app.invoke(inputs)
72
+
73
+ # On renvoie le résultat au format JSON propre
74
+ return ChatResponse(
75
+ intention=result.get("intention", "INCONNU"),
76
+ mot_cle=result.get("mot_cle", ""),
77
+ reponse_texte=result.get("final_response", "Désolé, une erreur est survenue lors de la recherche.")
78
+ )
79
+
80
+ except Exception as e:
81
+ # S'il y a un crash, on renvoie une erreur 500 propre au frontend
82
+ raise HTTPException(status_code=500, detail=str(e))
83
+
84
+
85
+ @app.post("/api/audio", response_model=ChatResponse)
86
+ async def audio_endpoint(
87
+ user_lat: float = Form(...),
88
+ user_lon: float = Form(...),
89
+ file: UploadFile = File(...)
90
+ ):
91
+ temp_file_path = f"temp_{file.filename}"
92
+
93
+ try:
94
+ # 1. Sauvegarde
95
+ with open(temp_file_path, "wb") as buffer:
96
+ shutil.copyfileobj(file.file, buffer)
97
+
98
+ # 2. Transcription
99
+ texte_transcrit = transcribe_audio(temp_file_path)
100
+ print(f"[VOCAL] Message transcrit : {texte_transcrit}")
101
+
102
+ # 3. Appel LangGraph
103
+ print("[INFO] : Lancement du Graph")
104
+ inputs = {
105
+ "user_message": str(texte_transcrit),
106
+ "user_lat": float(user_lat),
107
+ "user_lon": float(user_lon)
108
+ }
109
+
110
+ result = langgraph_app.invoke(inputs)
111
+
112
+ # 4. RETOUR UNIFIÉ
113
+ return ChatResponse(
114
+ intention=result.get("intention", "INCONNU"),
115
+ mot_cle=result.get("mot_cle", ""),
116
+ reponse_texte=result.get("final_response", "Désolé, une erreur est survenue lors de la recherche.")
117
+ )
118
+
119
+ except Exception as e:
120
+ print(f"Erreur Audio : {e}")
121
+ raise HTTPException(status_code=500, detail=f"Erreur : {str(e)}")
122
+
123
+ finally:
124
+ if os.path.exists(temp_file_path):
125
+ os.remove(temp_file_path)
126
+
127
+
128
+ # --- LANCEMENT DU SERVEUR ---
129
+ if __name__ == "__main__":
130
+ print("[INFO] Démarrage de l'API Nova Health sur http://localhost:8000")
131
+ uvicorn.run(app, host="0.0.0.0", port=8000)
data/finetuning_dataset.jsonl ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {"timestamp": "2026-03-25T17:35:11.044811", "messages": [{"role": "user", "content": "Je recherche une pharmacie ?"}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
2
+ {"timestamp": "2026-03-25T17:36:22.184748", "messages": [{"role": "user", "content": "j'ai tres mal au pieds "}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"orthopédiste\"}"}]}
3
+ {"timestamp": "2026-03-25T17:40:15.984261", "messages": [{"role": "user", "content": "j'ai tres mal au pieds "}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"orthopédiste\"}"}]}
4
+ {"timestamp": "2026-03-25T17:53:53.209742", "messages": [{"role": "user", "content": "Salut"}, {"role": "assistant", "content": "{\"categorie\": \"INCONNU\", \"mot_cle\": \"\"}"}]}
5
+ {"timestamp": "2026-03-25T17:54:17.423431", "messages": [{"role": "user", "content": "Comment tu vas !?"}, {"role": "assistant", "content": "{\"categorie\": \"INCONNU\", \"mot_cle\": \"\"}"}]}
6
+ {"timestamp": "2026-03-25T17:57:21.096039", "messages": [{"role": "user", "content": "J'ai mal a la tête !?"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"neurologue\"}"}]}
7
+ {"timestamp": "2026-03-25T18:12:28.671667", "messages": [{"role": "user", "content": "je recherche un pédiatre !?"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"pédiatre\"}"}]}
8
+ {"timestamp": "2026-03-25T18:19:47.991063", "messages": [{"role": "user", "content": "je recherche un pédiatre !?"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"pédiatre\"}"}]}
9
+ {"timestamp": "2026-03-25T18:20:21.362024", "messages": [{"role": "user", "content": "je recherche une pédiatrie !?"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"pédiatrie\"}"}]}
10
+ {"timestamp": "2026-03-25T18:20:48.677926", "messages": [{"role": "user", "content": "je recherche une pédiatre !?"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"pédiatre\"}"}]}
11
+ {"timestamp": "2026-03-25T18:24:15.915410", "messages": [{"role": "user", "content": "où est ce que je peux trouver un pédiatre"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"pédiatrie\"}"}]}
12
+ {"timestamp": "2026-03-25T18:24:35.214389", "messages": [{"role": "user", "content": "où est ce que je peux trouver un pédiatre"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"pédiatrie\"}"}]}
13
+ {"timestamp": "2026-03-25T23:29:07.900516", "messages": [{"role": "user", "content": "j'ai tres mal au pieds "}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"podiatrie\"}"}]}
14
+ {"timestamp": "2026-03-25T23:29:25.543983", "messages": [{"role": "user", "content": "j'ai tres mal au pieds "}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"podiatrie\"}"}]}
15
+ {"timestamp": "2026-03-26T01:18:38.962149", "messages": [{"role": "user", "content": "je recherche un pediatre"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"pédiatrie\"}"}]}
16
+ {"timestamp": "2026-03-26T01:19:26.148374", "messages": [{"role": "user", "content": "je recherche un spécialiste pour soigner mes enfants"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"pédiatrie\"}"}]}
17
+ {"timestamp": "2026-03-26T01:22:32.351642", "messages": [{"role": "user", "content": "je recherche un medecin generaliste"}, {"role": "assistant", "content": "{\"categorie\": \"ORIENTATION\", \"mot_cle\": \"\"}"}]}
18
+ {"timestamp": "2026-03-26T01:29:28.086462", "messages": [{"role": "user", "content": "je recherche un cardiologue"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"cardiologie\"}"}]}
19
+ {"timestamp": "2026-03-26T01:39:39.098727", "messages": [{"role": "user", "content": "je recherche un cardiologue"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"cardiologie\"}"}]}
20
+ {"timestamp": "2026-03-26T01:40:24.371453", "messages": [{"role": "user", "content": "je recherche un cardiologue"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"cardiologie\"}"}]}
21
+ {"timestamp": "2026-03-26T01:42:07.794359", "messages": [{"role": "user", "content": "je recherche un cardiologu"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"cardiologie\"}"}]}
22
+ {"timestamp": "2026-03-26T01:43:41.254338", "messages": [{"role": "user", "content": "je recherche un cardiologue"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"cardiologie\"}"}]}
23
+ {"timestamp": "2026-03-26T01:45:16.333679", "messages": [{"role": "user", "content": "je recherche un cardiologu"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"cardiologie\"}"}]}
24
+ {"timestamp": "2026-03-26T01:49:07.889329", "messages": [{"role": "user", "content": "je recherche un cardiologue"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"cardiologie\"}"}]}
25
+ {"timestamp": "2026-03-26T01:59:01.586599", "messages": [{"role": "user", "content": "je recherche un cardiologue"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"cardiologie\"}"}]}
26
+ {"timestamp": "2026-03-26T01:59:43.935602", "messages": [{"role": "user", "content": "je recherche une pharmacies"}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
27
+ {"timestamp": "2026-03-26T02:02:15.051402", "messages": [{"role": "user", "content": "je recherche pharmacie de garde"}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
28
+ {"timestamp": "2026-03-26T02:03:27.105631", "messages": [{"role": "user", "content": "Saluut comment tu vas !?"}, {"role": "assistant", "content": "{\"categorie\": \"INCONNU\", \"mot_cle\": \"\"}"}]}
29
+ {"timestamp": "2026-03-26T02:08:59.793440", "messages": [{"role": "user", "content": "Je recherches les pharmacie de garde"}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
30
+ {"timestamp": "2026-03-26T02:09:49.780263", "messages": [{"role": "user", "content": "Je recherches les pharmacie de garde"}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
31
+ {"timestamp": "2026-03-26T02:14:04.479515", "messages": [{"role": "user", "content": "Je recherches les pharmacie de garde"}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
32
+ {"timestamp": "2026-03-26T02:19:51.996416", "messages": [{"role": "user", "content": "je fais de la fievre et j 'ai besoin de voir un medecin"}, {"role": "assistant", "content": "{\"categorie\": \"ORIENTATION\", \"mot_cle\": \"\"}"}]}
33
+ {"timestamp": "2026-03-26T02:21:04.691359", "messages": [{"role": "user", "content": "je fais de la fievre et j ai besoin de voir un medecin"}, {"role": "assistant", "content": "{\"categorie\": \"ORIENTATION\", \"mot_cle\": \"\"}"}]}
34
+ {"timestamp": "2026-03-26T02:24:50.052640", "messages": [{"role": "user", "content": "je fais de la fievre et j ai besoin de voir un medecin"}, {"role": "assistant", "content": "{\"categorie\": \"ORIENTATION\", \"mot_cle\": \"\"}"}]}
35
+ {"timestamp": "2026-03-26T02:35:29.689165", "messages": [{"role": "user", "content": "je fais de la fievre et j ai besoin de voir un medecin"}, {"role": "assistant", "content": "{\"categorie\": \"ORIENTATION\", \"mot_cle\": \"\"}"}]}
36
+ {"timestamp": "2026-03-26T02:37:30.868528", "messages": [{"role": "user", "content": "je fais de la fievre et j ai besoin de voir un medecin"}, {"role": "assistant", "content": "{\"categorie\": \"ORIENTATION\", \"mot_cle\": \"\"}"}]}
37
+ {"timestamp": "2026-03-26T03:01:56.188466", "messages": [{"role": "user", "content": "je fais de la fievre et j ai besoin de voir un medecin"}, {"role": "assistant", "content": "{\"categorie\": \"ORIENTATION\", \"mot_cle\": \"\"}"}]}
38
+ {"timestamp": "2026-03-26T03:03:05.646253", "messages": [{"role": "user", "content": "je veux aller a la pharmacie"}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
39
+ {"timestamp": "2026-03-26T03:03:43.558212", "messages": [{"role": "user", "content": "je cheche un gynecologue"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"maternité\"}"}]}
40
+ {"timestamp": "2026-03-26T03:04:14.888236", "messages": [{"role": "user", "content": "je fais de la fievre"}, {"role": "assistant", "content": "{\"categorie\": \"ORIENTATION\", \"mot_cle\": \"\"}"}]}
41
+ {"timestamp": "2026-03-26T03:11:03.225954", "messages": [{"role": "user", "content": "je fais de la fievre"}, {"role": "assistant", "content": "{\"categorie\": \"ORIENTATION\", \"mot_cle\": \"\"}"}]}
42
+ {"timestamp": "2026-03-26T03:14:57.801055", "messages": [{"role": "user", "content": "je fais de la fievre"}, {"role": "assistant", "content": "{\"categorie\": \"ORIENTATION\", \"mot_cle\": \"\"}"}]}
43
+ {"timestamp": "2026-03-26T03:15:35.628768", "messages": [{"role": "user", "content": "je recherche un sexologue"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"sexologie\"}"}]}
44
+ {"timestamp": "2026-03-26T03:19:13.296489", "messages": [{"role": "user", "content": "ma femme enceinte de 8 mois a des douleurs"}, {"role": "assistant", "content": "{\"categorie\": \"SPECIALISTE\", \"mot_cle\": \"maternité\"}"}]}
45
+ {"timestamp": "2026-03-26T03:38:52.846270", "messages": [{"role": "user", "content": " Bonsoir, je recherche une pharmacie de garde proche de moi. Merci."}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
46
+ {"timestamp": "2026-03-26T03:39:18.871398", "messages": [{"role": "user", "content": " Bonsoir, je recherche une pharmacie de garde proche de moi. Merci."}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
47
+ {"timestamp": "2026-03-26T03:42:03.520544", "messages": [{"role": "user", "content": " Bonsoir, je recherche une pharmacie de garde proche de moi. Merci."}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
48
+ {"timestamp": "2026-03-26T03:42:23.167446", "messages": [{"role": "user", "content": " Bonsoir, je recherche une pharmacie de garde proche de moi. Merci."}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
49
+ {"timestamp": "2026-03-26T03:51:15.969948", "messages": [{"role": "user", "content": " Bonsoir, je recherche une pharmacie de garde proche de moi. Merci"}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
50
+ {"timestamp": "2026-03-26T03:52:03.999730", "messages": [{"role": "user", "content": " Bonsoir, je recherche une pharmacie de garde proche de moi. Merci."}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
51
+ {"timestamp": "2026-03-26T03:55:55.213240", "messages": [{"role": "user", "content": " Bonsoir, je recherche une pharmacie de garde proche de moi. Merci."}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
52
+ {"timestamp": "2026-03-26T03:56:13.138699", "messages": [{"role": "user", "content": " Bonsoir, je fais de la fièvre et j'ai besoin d'aide."}, {"role": "assistant", "content": "{\"categorie\": \"ORIENTATION\", \"mot_cle\": \"\"}"}]}
53
+ {"timestamp": "2026-03-26T04:01:10.919057", "messages": [{"role": "user", "content": " Bonsoir, je fais de la fièvre et j'ai besoin d'aide."}, {"role": "assistant", "content": "{\"categorie\": \"ORIENTATION\", \"mot_cle\": \"\"}"}]}
54
+ {"timestamp": "2026-03-26T04:01:39.094206", "messages": [{"role": "user", "content": " Bonsoir, je recherche une pharmacie de garde proche de moi. Merci."}, {"role": "assistant", "content": "{\"categorie\": \"PHARMACIE\", \"mot_cle\": \"\"}"}]}
data/nova_health.db DELETED
Binary file (45.1 kB)
 
data/pharmacies_cache.json CHANGED
@@ -1,380 +1,407 @@
1
  [
2
  {
3
- "nom": "PHARMACIE MAWUNYO",
4
- "quartier": "Agoè Sogbossito",
5
- "contacts": "98 23 38 30",
6
- "latitude": "6.254869000336117",
7
- "longitude": "1.1712071560981412",
8
- "map_link": "https://maps.google.com/?q=6.254869000336117,1.1712071560981412",
9
- "adresse": "Route de Mission Tové, Non loin de la Station OANDO Agoè Sogbossito"
10
  },
11
  {
12
- "nom": "PHARMACIE DENIS",
13
  "quartier": "AGOE",
14
- "contacts": "93 08 46 40 / 70 12 35 85",
15
- "latitude": "6.2477146",
16
- "longitude": "1.1529594",
17
- "map_link": "https://maps.google.com/?q=6.2477146,1.1529594",
18
- "adresse": "Agoè Kové, Carrefour KPOGLI"
19
  },
20
  {
21
- "nom": "PHARMACIE ABRAHAM",
22
- "quartier": "LOMÉ",
23
- "contacts": "22 50 10 00 / 92 25 99 83",
24
- "latitude": "6.2358092",
25
- "longitude": "1.1667484",
26
- "map_link": "https://maps.google.com/?q=6.2358092,1.1667484",
27
- "adresse": "Agoè Lohopé Kossigan"
28
  },
29
  {
30
- "nom": "PHARMACIE M'BA",
31
  "quartier": "AGOE",
32
- "contacts": "70 27 81 81 / 99 76 81 81",
33
- "latitude": "6.2716598",
34
- "longitude": "1.1464673",
35
- "map_link": "https://maps.google.com/?q=6.2716598,1.1464673",
36
- "adresse": "13 BP 341 Lomé. Route de Kovié, 500 mètres après le marché de LEGBASSITO. "
37
  },
38
  {
39
- "nom": "PHARMACIE EMMAUS",
40
- "quartier": "AGOE NYIVE",
41
- "contacts": "22 51 29 19 / 22 40 25 04",
42
- "latitude": "6.2359286",
43
- "longitude": "1.1918434",
44
- "map_link": "https://maps.google.com/?q=6.2359286,1.1918434",
45
- "adresse": "Route de Mission-Tové, Agoè-Nyivé BP 20492"
46
  },
47
  {
48
- "nom": "PHARMACIE VITA FLORE",
49
- "quartier": "LOME",
50
- "contacts": "22 27 06 36",
51
- "latitude": "6.2219499",
52
- "longitude": "1.163045",
53
- "map_link": "https://maps.google.com/?q=6.2219499,1.163045",
54
- "adresse": "Baguida, BP 80531"
55
  },
56
  {
57
- "nom": "PHARMACIE DE LA CHARITE",
58
- "quartier": "AGOE NYIVE",
59
- "contacts": "22 25 12 60",
60
- "latitude": "6.2638511",
61
- "longitude": "1.1337231",
62
- "map_link": "https://maps.google.com/?q=6.2638511,1.1337231",
63
- "adresse": "Non loin de CEG agoè nyivé centre, BP 7856"
64
  },
65
  {
66
- "nom": "PHARMACIE TAKOE",
67
- "quartier": "AGOE ZONGO",
68
- "contacts": "22 35 27 12 / 90 02 34 59",
69
- "latitude": "6.253209",
70
- "longitude": "1.2063726",
71
- "map_link": "https://maps.google.com/?q=6.253209,1.2063726",
72
- "adresse": "Rte d’Atakpamé, Face Terminal Sahel, Togblekopé, BP 8408"
73
  },
74
  {
75
- "nom": "PHARMACIE NABINE",
76
  "quartier": "AGOE",
77
- "contacts": "93 36 26 26 / 98 97 97 96",
78
- "latitude": "6.2180871",
79
- "longitude": "1.1825304",
80
- "map_link": "https://maps.google.com/?q=6.2180871,1.1825304",
81
- "adresse": "Site à Agoè Anomé, dit plateau (Route Bar le Plateau)"
82
  },
83
  {
84
- "nom": "PHARMACIE ADOUNI",
85
  "quartier": "AGOE",
86
- "contacts": "70 39 39 39",
87
- "latitude": "6.218597315389508",
88
- "longitude": "1.1489563691587497",
89
- "map_link": "https://maps.google.com/?q=6.218597315389508,1.1489563691587497",
90
- "adresse": "Vakposito logogome, carrefour AISED"
91
  },
92
  {
93
- "nom": "PHARMACIE GANFAT",
94
- "quartier": "AGOE",
95
- "contacts": "22 55 08 15 / 70 22 15 15",
96
- "latitude": "6.2372998",
97
- "longitude": "1.1277133",
98
- "map_link": "https://maps.google.com/?q=6.2372998,1.1277133",
99
- "adresse": "Agoè Daliko près du Carf EDEM (Camp GP)"
100
  },
101
  {
102
- "nom": "PHARMACIE LAUS DEO",
103
  "quartier": "LOME",
104
- "contacts": "22 25 15 05 / 22 31 54 52",
105
- "latitude": "6.2069734",
106
- "longitude": "1.1808951",
107
- "map_link": "https://maps.google.com/?q=6.2069734,1.1808951",
108
- "adresse": "Route de Léo 2000, face clinique Bethesda, Adidoadin, 05 BP 21"
109
  },
110
  {
111
- "nom": "PHARMACIE DELALI",
112
- "quartier": "AGOE NYIVE",
113
- "contacts": "22 25 83 31 / 23 36 42 51",
114
- "latitude": "6.2079146",
115
- "longitude": "1.1930054",
116
- "map_link": "https://maps.google.com/?q=6.2079146,1.1930054",
117
- "adresse": "Face CMS de cacaveli, 04 BP 225"
118
  },
119
  {
120
- "nom": "PHARMACIE EL-SALI",
121
- "quartier": "LOME",
122
- "contacts": "70 12 44 44",
123
- "latitude": "6.2201679",
124
- "longitude": "1.1231497",
125
- "map_link": "https://maps.google.com/?q=6.2201679,1.1231497",
126
- "adresse": "Rte Lomé-Kpalimé, Aflao Apédokoè Gbomamé, à 50 m de la quaincaillerue MACO"
127
  },
128
  {
129
- "nom": "PHARMACIE BESDA",
130
- "quartier": "",
131
- "contacts": "23 37 10 56",
132
- "latitude": "6.1946918",
133
- "longitude": "1.1537811",
134
- "map_link": "https://maps.google.com/?q=6.1946918,1.1537811",
135
- "adresse": "2, rue Batoumé, Bawakondji, Assahoun, BP 70"
136
  },
137
  {
138
- "nom": "PHARMACIE MAINA",
139
  "quartier": "AGOE NYIVE",
140
- "contacts": "22 33 65 34",
141
- "latitude": "6.1920183",
142
- "longitude": "1.1751296",
143
- "map_link": "https://maps.google.com/?q=6.1920183,1.1751296",
144
- "adresse": "Marché Agoè-Assiyéyé"
145
  },
146
  {
147
- "nom": "PHARMACIE NATION",
148
  "quartier": "LOME",
149
- "contacts": "22 25 99 65",
150
- "latitude": "6.1922419",
151
- "longitude": "1.1888177",
152
- "map_link": "https://maps.google.com/?q=6.1922419,1.1888177",
153
- "adresse": "Totsi en face de l'agence ECOBANK"
154
  },
155
  {
156
- "nom": "PHARMACIE CONSEIL",
157
- "quartier": "LOME",
158
- "contacts": "93 10 92 92 / 96 80 21 37",
159
- "latitude": "6.1937183",
160
- "longitude": "1.1280846",
161
- "map_link": "https://maps.google.com/?q=6.1937183,1.1280846",
162
- "adresse": "Carrefour du CEG Sagbado Logoté"
163
  },
164
  {
165
- "nom": "PHARMACIE EPIPHANIA",
166
  "quartier": "LOME",
167
- "contacts": "22 25 02 62 / 23 20 10 52",
168
- "latitude": "6.1805102",
169
- "longitude": "1.1612939",
170
- "map_link": "https://maps.google.com/?q=6.1805102,1.1612939",
171
- "adresse": "Rue Lapampa, carrefour Agbénadon, Adidogomé, 04 BP 30446"
172
  },
173
  {
174
- "nom": "PHARMACIE DU POINT E",
175
  "quartier": "LOME",
176
- "contacts": "22 51 91 71",
177
- "latitude": "6.1813289",
178
- "longitude": "1.1904931",
179
- "map_link": "https://maps.google.com/?q=6.1813289,1.1904931",
180
- "adresse": "506, rue 129, Aflao Gakli, djidjolé, 08 BP 8589"
181
  },
182
  {
183
- "nom": "PHARMACIE VERTE",
184
  "quartier": "LOME",
185
- "contacts": "22 25 03 26 / 23 35 26 26",
186
- "latitude": "6.1859618",
187
- "longitude": "1.2047908",
188
- "map_link": "https://maps.google.com/?q=6.1859618,1.2047908",
189
- "adresse": "Avenue du RPT Bè Klikamé, BP 81297"
190
  },
191
  {
192
- "nom": "PHARMACIE SANTA MADONA",
 
 
 
 
 
 
 
 
 
193
  "quartier": "LOME",
194
- "contacts": "70 01 03 03 / 96 68 03 03",
195
- "latitude": "6.2139633",
196
- "longitude": "1.2376909",
197
- "map_link": "https://maps.google.com/?q=6.2139633,1.2376909",
198
- "adresse": "Kégué, face Kader COUGBADJA et l'Eglise catholique Ste Thèrese"
199
  },
200
  {
201
- "nom": "PHARMACIE NOTRE DAME DE LA TRINITE",
202
  "quartier": "LOME",
203
- "contacts": "22 21 27 80",
204
- "latitude": "6.1749711",
205
- "longitude": "1.1869585",
206
- "map_link": "https://maps.google.com/?q=6.1749711,1.1869585",
207
- "adresse": "30, Bd. De la paix, super Taco, BP 60154"
208
  },
209
  {
210
- "nom": "PHARMACIE AMEN",
211
- "quartier": "AGOE",
212
- "contacts": "90 88 55 88 / 97 18 02 02",
213
- "latitude": "6.3202621",
214
- "longitude": "1.2234323",
215
- "map_link": "https://maps.google.com/?q=6.3202621,1.2234323",
216
- "adresse": "Marché Adétikopé, près de l'Eglise Catholique Christ-Roi"
217
  },
218
  {
219
- "nom": "PHARMACIE DE LA CITE",
220
  "quartier": "LOME",
221
- "contacts": "22 25 01 25 / 22 37 01 07",
222
- "latitude": "6.1711653",
223
- "longitude": "1.1878512",
224
- "map_link": "https://maps.google.com/?q=6.1711653,1.1878512",
225
- "adresse": "Bd ; du 30 Août cité n’danida BP 8461"
226
  },
227
  {
228
- "nom": "PHARMACIE GBOSSIME",
229
  "quartier": "LOME",
230
- "contacts": "22 22 50 50",
231
- "latitude": "6.1623605",
232
- "longitude": "1.2100301",
233
- "map_link": "https://maps.google.com/?q=6.1623605,1.2100301",
234
- "adresse": "405, Bd. De la Kara, Gbossime, BP 80859"
235
  },
236
  {
237
- "nom": "PHARMACIE RAOUDHA",
238
  "quartier": "LOME",
239
- "contacts": "22 61 39 39 / 22 35 70 00",
240
- "latitude": "6.1946095",
241
- "longitude": "1.2516629",
242
- "map_link": "https://maps.google.com/?q=6.1946095,1.2516629",
243
- "adresse": "4495, Bd. Du Zio, Hédzranawoé, 3 BP 30153"
244
  },
245
  {
246
- "nom": "PHARMACIE FOREVER",
247
  "quartier": "LOME",
248
- "contacts": "22 26 11 77 / 22 42 42 22",
249
- "latitude": "6.1596623",
250
- "longitude": "1.2242197",
251
- "map_link": "https://maps.google.com/?q=6.1596623,1.2242197",
252
- "adresse": "142, avenue des kondona, forever, BP 4884"
253
  },
254
  {
255
- "nom": "PHARMACIE LUMEN",
256
  "quartier": "LOME",
257
- "contacts": "23 38 68 36",
258
- "latitude": "6.2513181",
259
- "longitude": "1.2794971",
260
- "map_link": "https://maps.google.com/?q=6.2513181,1.2794971",
261
- "adresse": "Avenue de la victoire, tokoin Casablanca, 01 BP 29"
262
  },
263
  {
264
- "nom": "PHARMACIE DE L’ESPERANCE",
265
- "quartier": "LOME",
266
- "contacts": "22 21 01 28",
267
- "latitude": "6.1539595",
268
- "longitude": "1.2208199",
269
- "map_link": "https://maps.google.com/?q=6.1539595,1.2208199",
270
- "adresse": "Rue de l’ogou, en face du lycée française nyikonakpo, BP 719"
271
  },
272
  {
273
- "nom": "PHARMACIE ROBERTSON",
274
  "quartier": "LOME",
275
- "contacts": "22 22 28 41 / 23 20 61 11",
276
- "latitude": "6.1353768",
277
- "longitude": "1.2089434",
278
- "map_link": "https://maps.google.com/?q=6.1353768,1.2089434",
279
- "adresse": "31 avenue François Mittérand, nyékonakpoè, BP 81670"
280
  },
281
  {
282
- "nom": "PHARMACIE LA MISERICORDE",
283
  "quartier": "LOME",
284
- "contacts": "23 38 47 62 / 22 27 17 73",
285
- "latitude": "6.15674663",
286
- "longitude": "1.2526435",
287
- "map_link": "https://maps.google.com/?q=6.15674663,1.2526435",
288
- "adresse": "52, Boulevard, de l’Oti, Bè-kpota, BP 8223"
289
  },
290
  {
291
- "nom": "PHARMACIE KPEHENOU",
292
  "quartier": "LOME",
293
- "contacts": "22 21 32 24 / 22 35 25 03",
294
- "latitude": "6.1384656",
295
- "longitude": "1.2348407",
296
- "map_link": "https://maps.google.com/?q=6.1384656,1.2348407",
297
- "adresse": "Boulevard Felix Houphouët Boigny, BP 12470"
298
  },
299
  {
300
- "nom": "PHARMACIE 2000",
301
  "quartier": "LOME",
302
- "contacts": "22 70 48 25 / 22 70 01 69",
303
- "latitude": "6.1638256",
304
- "longitude": "1.2685838",
305
- "map_link": "https://maps.google.com/?q=6.1638256,1.2685838",
306
- "adresse": "Bè kpota, BP 61194"
307
  },
308
  {
309
- "nom": "PHARMACIE DES OLIVIERS",
310
  "quartier": "LOME",
311
- "contacts": "22 27 01 34",
312
- "latitude": "6.152032",
313
- "longitude": "1.2600352",
314
- "map_link": "https://maps.google.com/?q=6.152032,1.2600352",
315
- "adresse": "266 boulevard Félix Boigny, Akodésséwa, BP 8480"
316
  },
317
  {
318
- "nom": "PHARMACIE DU CHATEAU D’EAU",
319
  "quartier": "LOME",
320
- "contacts": "22 21 57 51",
321
- "latitude": "6.1371315",
322
- "longitude": "1.2468195",
323
- "map_link": "https://maps.google.com/?q=6.1371315,1.2468195",
324
- "adresse": "Avenue augustino de souza, bè château, BP 60141"
325
  },
326
  {
327
- "nom": "PHARMACIE JEANNE D'ARC",
328
- "quartier": "ANEHO",
329
- "contacts": "22 22 08 01",
330
- "latitude": "6.1273136",
331
- "longitude": "1.2336277",
332
- "map_link": "https://maps.google.com/?q=6.1273136,1.2336277",
333
- "adresse": "Sur l’ancienne route d’Aného, BP 368"
334
  },
335
  {
336
- "nom": "PHARMACIE CHRIST ROI",
337
  "quartier": "LOME",
338
- "contacts": "22 27 46 66",
339
- "latitude": "6.169822",
340
- "longitude": "1.2984214",
341
- "map_link": "https://maps.google.com/?q=6.169822,1.2984214",
342
- "adresse": "Raffinerie vers le petit marché, kagomé, BP 1409"
343
  },
344
  {
345
- "nom": "PHARMACIE BAGUIDA",
346
  "quartier": "LOME",
347
- "contacts": "22 35 47 77",
348
- "latitude": "6.1700753",
349
- "longitude": "1.3237638",
350
- "map_link": "https://maps.google.com/?q=6.1700753,1.3237638",
351
- "adresse": "Rte baguida-dévégo, BP 60767"
352
  },
353
  {
354
- "nom": "PHARMACIE AVEPOZO",
355
  "quartier": "LOME",
356
- "contacts": "22 27 04 86",
357
- "latitude": "6.1698577",
358
- "longitude": "1.343146",
359
- "map_link": "https://maps.google.com/?q=6.1698577,1.343146",
360
- "adresse": "A 600m restaurant Alice, Bè-kome, avépozo, 04 BP 353 Lomé 04"
361
  },
362
  {
363
- "nom": "PHARMACIE BIEN ETRE",
364
- "quartier": "LOME",
365
- "contacts": "22 26 45 16",
366
- "latitude": "6.2855948",
367
- "longitude": "1.5776124",
368
- "map_link": "https://maps.google.com/?q=6.2855948,1.5776124",
369
- "adresse": "Boulevard du haho, hédzranawoé, BP 2933"
370
  },
371
  {
372
- "nom": "PHARMACIE SAINTE MARIE",
373
  "quartier": "LOME",
374
- "contacts": "22 21 85 58",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
  "latitude": "0.0",
376
  "longitude": "0.0",
377
  "map_link": "",
378
- "adresse": "Avenue de la libération, Limusco, Tokoin Ramco, BP 297"
379
  }
380
  ]
 
1
  [
2
  {
3
+ "nom": "PHARMACIE LA NOUVELLE TULIPE",
4
+ "quartier": "LOME",
5
+ "contacts": "99 47 00 70",
6
+ "latitude": "6.2608333",
7
+ "longitude": "1.16075",
8
+ "map_link": "https://maps.google.com/?q=6.2608333,1.16075",
9
+ "adresse": "Rte de Mission-Tové, près de la Station CAP Agoè-légbassito"
10
  },
11
  {
12
+ "nom": "PHARMACIE LA BARAKA",
13
  "quartier": "AGOE",
14
+ "contacts": "90 17 49 28 / 70 41 44 13",
15
+ "latitude": "6.2421387",
16
+ "longitude": "1.1664511",
17
+ "map_link": "https://maps.google.com/?q=6.2421387,1.1664511",
18
+ "adresse": "Agoe Logopé, non loin de l'Ecoke la BRUYERE à proximité du camp GP"
19
  },
20
  {
21
+ "nom": "PHARMACIE DIVINA GRACIA",
22
+ "quartier": "AGOE",
23
+ "contacts": "93 83 91 00 / 96 80 10 21",
24
+ "latitude": "6.2327797",
25
+ "longitude": "1.1868497",
26
+ "map_link": "https://maps.google.com/?q=6.2327797,1.1868497",
27
+ "adresse": "Agoè fiovi, rond point Cool Catche"
28
  },
29
  {
30
+ "nom": "PHARMACIE TCHEP'SON",
31
  "quartier": "AGOE",
32
+ "contacts": "96 90 04 64 / 70 42 94 41",
33
+ "latitude": "6.2590019",
34
+ "longitude": "1.1991617",
35
+ "map_link": "https://maps.google.com/?q=6.2590019,1.1991617",
36
+ "adresse": "Face terminal du Sahel, Agoè zongo"
37
  },
38
  {
39
+ "nom": "PHARMACIE GRATITUDE",
40
+ "quartier": "Agoè Légbassito",
41
+ "contacts": "92 18 94 85",
42
+ "latitude": "6.2646808",
43
+ "longitude": "1.133599",
44
+ "map_link": "https://maps.google.com/?q=6.2646808,1.133599",
45
+ "adresse": "Grand contournement non loin du carrefour avinato à 100m de la clinique OASIS "
46
  },
47
  {
48
+ "nom": "PHARMACIE LA MAIN DE DIEU",
49
+ "quartier": "AGOE",
50
+ "contacts": "22 52 77 55",
51
+ "latitude": "6.2349799",
52
+ "longitude": "1.2003657",
53
+ "map_link": "https://maps.google.com/?q=6.2349799,1.2003657",
54
+ "adresse": "Agoè nouveau marché, vers le camp de police"
55
  },
56
  {
57
+ "nom": "PHARMACIE YESHUA",
58
+ "quartier": "Agoè-Nyivé",
59
+ "contacts": "98772153 / 98772150",
60
+ "latitude": "6.2197903",
61
+ "longitude": "1.1567935",
62
+ "map_link": "https://maps.google.com/?q=6.2197903,1.1567935",
63
+ "adresse": "Agoè - Vakpossito vers l'école NDE, entre le CMS Mur et le CMS Maranatha"
64
  },
65
  {
66
+ "nom": "PHARMACIE ZOSSIME",
67
+ "quartier": "AGOE",
68
+ "contacts": "99 99 80 75 / 70 46 26 64",
69
+ "latitude": "6.2333748",
70
+ "longitude": "1.1391774",
71
+ "map_link": "https://maps.google.com/?q=6.2333748,1.1391774",
72
+ "adresse": "Zossimé, route de Sanguéra près du marché de Zossimé"
73
  },
74
  {
75
+ "nom": "PHARMACIE LE ROCHER",
76
  "quartier": "AGOE",
77
+ "contacts": "92 30 06 56 / 99 08 05 01",
78
+ "latitude": "6.2461716",
79
+ "longitude": "1.2071869",
80
+ "map_link": "https://maps.google.com/?q=6.2461716,1.2071869",
81
+ "adresse": "Agoè Zongo, sur la nationale N°1, près du terrain de jeu de Golf"
82
  },
83
  {
84
+ "nom": "PHARMACIE CLEMENCE",
85
  "quartier": "AGOE",
86
+ "contacts": "70 19 35 35 / 70 21 26 26",
87
+ "latitude": "6.2199286",
88
+ "longitude": "1.1895335",
89
+ "map_link": "https://maps.google.com/?q=6.2199286,1.1895335",
90
+ "adresse": "Route de la Cour d'appel, entre la CEET et l'Ecole privée LA SOURCE"
91
  },
92
  {
93
+ "nom": "PHARMACIE DIEUDONNE",
94
+ "quartier": "AGOE NYIVE",
95
+ "contacts": "23 38 07 44",
96
+ "latitude": "6.2157404",
97
+ "longitude": "1.1374364",
98
+ "map_link": "https://maps.google.com/?q=6.2157404,1.1374364",
99
+ "adresse": "Route LEO 2000, non loin de FUCEC, Agoè-Téléssou, BP 7951"
100
  },
101
  {
102
+ "nom": "PHARMACIE MILLENAIRE",
103
  "quartier": "LOME",
104
+ "contacts": "22 51 64 31",
105
+ "latitude": "6.206914",
106
+ "longitude": "1.1873226",
107
+ "map_link": "https://maps.google.com/?q=6.206914,1.1873226",
108
+ "adresse": "Adidoadin, 05 BP 64"
109
  },
110
  {
111
+ "nom": "PHARMACIE APOLLON",
112
+ "quartier": "LOME",
113
+ "contacts": "22 31 01 07",
114
+ "latitude": "6.202853",
115
+ "longitude": "1.1644948",
116
+ "map_link": "https://maps.google.com/?q=6.202853,1.1644948",
117
+ "adresse": "Hétsiavi, avédji, 08 BP 80507"
118
  },
119
  {
120
+ "nom": "PHARMACIE EVA",
121
+ "quartier": "AGOE",
122
+ "contacts": "92163232",
123
+ "latitude": "6.24591",
124
+ "longitude": "1.1150278",
125
+ "map_link": "https://maps.google.com/?q=6.24591,1.1150278",
126
+ "adresse": "Sanguéra, non loin de T'OIL"
127
  },
128
  {
129
+ "nom": "PHARMACIE OSSAN",
130
+ "quartier": "LOME",
131
+ "contacts": "23 38 44 25 / 22 51 13 04",
132
+ "latitude": "6.201132",
133
+ "longitude": "1.1785749",
134
+ "map_link": "https://maps.google.com/?q=6.201132,1.1785749",
135
+ "adresse": "Carrefour d’Avédji, BP 869"
136
  },
137
  {
138
+ "nom": "PHARMACIE SAINT MICHEL",
139
  "quartier": "AGOE NYIVE",
140
+ "contacts": "22 51 70 22",
141
+ "latitude": "6.2152161",
142
+ "longitude": "1.2062228",
143
+ "map_link": "https://maps.google.com/?q=6.2152161,1.2062228",
144
+ "adresse": "Près de la Brasserie BB, 05 BP 201"
145
  },
146
  {
147
+ "nom": "PHARMACIE SILOE",
148
  "quartier": "LOME",
149
+ "contacts": "22 33 82 87",
150
+ "latitude": "6.2068567",
151
+ "longitude": "1.1387278",
152
+ "map_link": "https://maps.google.com/?q=6.2068567,1.1387278",
153
+ "adresse": "Carrefour Atigangomé, Adidogomé A pédokoe, 07 BP 7189"
154
  },
155
  {
156
+ "nom": "PHARMACIE SAINT ESPRIT",
157
+ "quartier": "AGOE NYIVE",
158
+ "contacts": "22 40 29 06",
159
+ "latitude": "6.2218567",
160
+ "longitude": "1.219288",
161
+ "map_link": "https://maps.google.com/?q=6.2218567,1.219288",
162
+ "adresse": "Route Agoè-Kégué, CEG Agoè Est, BP 1246"
163
  },
164
  {
165
+ "nom": "PHARMACIE ACTUELLE",
166
  "quartier": "LOME",
167
+ "contacts": "22 51 11 72 / 22 50 63 30",
168
+ "latitude": "6.1926065",
169
+ "longitude": "1.1418284",
170
+ "map_link": "https://maps.google.com/?q=6.1926065,1.1418284",
171
+ "adresse": "Route ségbé, sagbado, BP 3622"
172
  },
173
  {
174
+ "nom": "PHARMACIE VIGUEUR",
175
  "quartier": "LOME",
176
+ "contacts": "22 51 63 30 / 90 03 29 71",
177
+ "latitude": "6.1925619",
178
+ "longitude": "1.1986329",
179
+ "map_link": "https://maps.google.com/?q=6.1925619,1.1986329",
180
+ "adresse": "267, rue Agbalépédo, 05 BP 02"
181
  },
182
  {
183
+ "nom": "PHARMACIE ADIDOGOME",
184
  "quartier": "LOME",
185
+ "contacts": "22 25 54 85 / 22 50 54 85",
186
+ "latitude": "6.1850613",
187
+ "longitude": "1.1640512",
188
+ "map_link": "https://maps.google.com/?q=6.1850613,1.1640512",
189
+ "adresse": "Avenue du 30 Août, adidogomé, 04 BP 224 Lomé 04"
190
  },
191
  {
192
+ "nom": "PHARMACIE ASSURANCE",
193
+ "quartier": "AGOE",
194
+ "contacts": "93 08 76 76 / 96 82 76 76",
195
+ "latitude": "6.3208762",
196
+ "longitude": "1.2088685",
197
+ "map_link": "https://maps.google.com/?q=6.3208762,1.2088685",
198
+ "adresse": "Adétikopé, Nationale N° 1, non loin du marché"
199
+ },
200
+ {
201
+ "nom": "PHARMACIE DJIDJOLE",
202
  "quartier": "LOME",
203
+ "contacts": "22 25 65 12 / 23 20 95 55",
204
+ "latitude": "6.1804899",
205
+ "longitude": "1.1930898",
206
+ "map_link": "https://maps.google.com/?q=6.1804899,1.1930898",
207
+ "adresse": "93 rue Pya BP 8539"
208
  },
209
  {
210
+ "nom": "PHARMACIE DE L'AEROPORT",
211
  "quartier": "LOME",
212
+ "contacts": "22 26 21 22",
213
+ "latitude": "6.18244",
214
+ "longitude": "1.2055796",
215
+ "map_link": "https://maps.google.com/?q=6.18244,1.2055796",
216
+ "adresse": "631, bd ; du haho, imm ; SITO, hédzranawoé, BP 3717"
217
  },
218
  {
219
+ "nom": "PHARMACIE UNIVERS SANTE",
220
+ "quartier": "LOMÉ",
221
+ "contacts": "22 61 81 43 / 93 88 83 31",
222
+ "latitude": "6.1827033",
223
+ "longitude": "1.2124053",
224
+ "map_link": "https://maps.google.com/?q=6.1827033,1.2124053",
225
+ "adresse": "Bd. GNASSIMGBE Eyadéma, Cité OUA face a l'entrée du CHU-CAMPUS"
226
  },
227
  {
228
+ "nom": "PHARMACIE SAINT JOSEPH",
229
  "quartier": "LOME",
230
+ "contacts": "22 25 74 65",
231
+ "latitude": "6.1772853",
232
+ "longitude": "1.2029426",
233
+ "map_link": "https://maps.google.com/?q=6.1772853,1.2029426",
234
+ "adresse": "Rue Bretelle, Avenue de la RP, Bè Klikamé, BP 13000"
235
  },
236
  {
237
+ "nom": "PHARMACIE DES LILAS",
238
  "quartier": "LOME",
239
+ "contacts": "22 42 29 16",
240
+ "latitude": "6.1830855",
241
+ "longitude": "1.2332334",
242
+ "map_link": "https://maps.google.com/?q=6.1830855,1.2332334",
243
+ "adresse": "7 rue de kégué, en face du camp, BP 31000"
244
  },
245
  {
246
+ "nom": "PHARMACIE INTERNATIONALE",
247
  "quartier": "LOME",
248
+ "contacts": "22 26 89 94 / 99 90 89 66",
249
+ "latitude": "6.1832166",
250
+ "longitude": "1.2389391",
251
+ "map_link": "https://maps.google.com/?q=6.1832166,1.2389391",
252
+ "adresse": "1180, boulevard du Haho, Angle Nord, Assi yéyé Hédzranawoé, BP 1344"
253
  },
254
  {
255
+ "nom": "PHARMACIE DU CAMPUS",
256
  "quartier": "LOME",
257
+ "contacts": "22 21 56 32",
258
+ "latitude": "6.1629236",
259
+ "longitude": "1.2111689",
260
+ "map_link": "https://maps.google.com/?q=6.1629236,1.2111689",
261
+ "adresse": "Bd. De la Kara, adéwui, BP 20217"
262
  },
263
  {
264
+ "nom": "PHARMACIE DE LA LIBERATION",
265
  "quartier": "LOME",
266
+ "contacts": "22 22 25 25",
267
+ "latitude": "6.1533788",
268
+ "longitude": "1.2173758",
269
+ "map_link": "https://maps.google.com/?q=6.1533788,1.2173758",
270
+ "adresse": "199 avenue de la libération, tokoin trésor, BP 12045"
271
  },
272
  {
273
+ "nom": "PHARMACIE PROVIDENCE",
274
+ "quartier": "LOMÉ",
275
+ "contacts": "22 26 66 48",
276
+ "latitude": "6.1606858",
277
+ "longitude": "1.2316459",
278
+ "map_link": "https://maps.google.com/?q=6.1606858,1.2316459",
279
+ "adresse": "Boulevard Jean-Paul II"
280
  },
281
  {
282
+ "nom": "PHARMACIE SOURCE DE VIE",
283
  "quartier": "LOME",
284
+ "contacts": "22 22 45 71",
285
+ "latitude": "6.1471155",
286
+ "longitude": "1.2012943",
287
+ "map_link": "https://maps.google.com/?q=6.1471155,1.2012943",
288
+ "adresse": "Bd. De la victoire, Face Collège protestant, BP 147"
289
  },
290
  {
291
+ "nom": "PHARMACIE SAINTE RITA",
292
  "quartier": "LOME",
293
+ "contacts": "22 20 90 16",
294
+ "latitude": "6.1383352",
295
+ "longitude": "1.2281291",
296
+ "map_link": "https://maps.google.com/?q=6.1383352,1.2281291",
297
+ "adresse": "Rue de France, face Hôtel Sana, Doulassamé, BP 10046"
298
  },
299
  {
300
+ "nom": "PHARMACIE DE L’UNION",
301
  "quartier": "LOME",
302
+ "contacts": "22 27 71 64",
303
+ "latitude": "6.1602452",
304
+ "longitude": "1.2610987",
305
+ "map_link": "https://maps.google.com/?q=6.1602452,1.2610987",
306
+ "adresse": "Bd ; mafakassa Bè KPOTA BP 2735"
307
  },
308
  {
309
+ "nom": "PHARMACIE DES ETOILES",
310
  "quartier": "LOME",
311
+ "contacts": "22 22 45 04",
312
+ "latitude": "6.1320067",
313
+ "longitude": "1.2182941",
314
+ "map_link": "https://maps.google.com/?q=6.1320067,1.2182941",
315
+ "adresse": "10, avenue de la nouvelle marché, BP 3484"
316
  },
317
  {
318
+ "nom": "PHARMACIE HORIZON",
319
  "quartier": "LOME",
320
+ "contacts": "90 56 52 56 / 22 20 42 42",
321
+ "latitude": "6.1289741",
322
+ "longitude": "1.210742",
323
+ "map_link": "https://maps.google.com/?q=6.1289741,1.210742",
324
+ "adresse": "95, boulevard du 13 Janvier, Nyekonakpoè, 08 BP 81726"
325
  },
326
  {
327
+ "nom": "PHARMACIE AMESSIAME",
328
  "quartier": "LOME",
329
+ "contacts": "22 21 49 74 / 22 40 66 69",
330
+ "latitude": "6.1361035",
331
+ "longitude": "1.2320088",
332
+ "map_link": "https://maps.google.com/?q=6.1361035,1.2320088",
333
+ "adresse": "Bd. F H Boigny près du marché de Bè, BP 61720"
334
  },
335
  {
336
+ "nom": "PHARMACIE SANTE",
337
+ "quartier": "LOME",
338
+ "contacts": "22 21 58 41",
339
+ "latitude": "6.1308958",
340
+ "longitude": "1.2251543",
341
+ "map_link": "https://maps.google.com/?q=6.1308958,1.2251543",
342
+ "adresse": "674, rue du chemin de fer, 01 BP 1236"
343
  },
344
  {
345
+ "nom": "PHARMACIE DE SEGBE",
346
  "quartier": "LOME",
347
+ "contacts": "90 59 49 35 / 79 30 07 29",
348
+ "latitude": "6.1939325",
349
+ "longitude": "1.0440659",
350
+ "map_link": "https://maps.google.com/?q=6.1939325,1.0440659",
351
+ "adresse": "Ségbé, quartier Zanvi,, près de l'EPP et du CEG Ségbé"
352
  },
353
  {
354
+ "nom": "PHARMACIE ECLAIR",
355
  "quartier": "LOME",
356
+ "contacts": "22 22 75 11",
357
+ "latitude": "6.1425481",
358
+ "longitude": "1.2548651",
359
+ "map_link": "https://maps.google.com/?q=6.1425481,1.2548651",
360
+ "adresse": "Rue avénou, bè ahligo, BP 81297"
361
  },
362
  {
363
+ "nom": "PHARMACIE LE PROGRES",
364
  "quartier": "LOME",
365
+ "contacts": "22 35 86 55 / 22 27 14 63",
366
+ "latitude": "6.166686",
367
+ "longitude": "1.2810575",
368
+ "map_link": "https://maps.google.com/?q=6.166686,1.2810575",
369
+ "adresse": "Akodésséwa Kponou (Zorro-bar), 06 BP 60986"
370
  },
371
  {
372
+ "nom": "PHARMACIE SAINT PHILIPPE",
373
+ "quartier": "AGOE",
374
+ "contacts": "90 67 33 24 / 99 99 80 04",
375
+ "latitude": "6.2280254",
376
+ "longitude": "1.0259728",
377
+ "map_link": "https://maps.google.com/?q=6.2280254,1.0259728",
378
+ "adresse": "Zanguéra, Route Lomé-Kpalimé, près de la station de service OANDO"
379
  },
380
  {
381
+ "nom": "PHARMACIE DE L'EDEN",
382
  "quartier": "LOME",
383
+ "contacts": "70 42 13 98",
384
+ "latitude": "6.1611581",
385
+ "longitude": "1.306967",
386
+ "map_link": "https://maps.google.com/?q=6.1611581,1.306967",
387
+ "adresse": "Route d'Anèo, face à la cité Baguida"
388
+ },
389
+ {
390
+ "nom": "PHARMACIE SAINT PIO",
391
+ "quartier": "KLOBATEME",
392
+ "contacts": "93404040 / 96868686",
393
+ "latitude": "0.0",
394
+ "longitude": "0.0",
395
+ "map_link": "",
396
+ "adresse": "Klobatèmé, non loin du CMS Klobatèmé à côté du Complexe Scolaire Bon Samaritain"
397
+ },
398
+ {
399
+ "nom": "PHARMACIE WASTINE",
400
+ "quartier": "Lomé",
401
+ "contacts": "92611700 / 22518119",
402
  "latitude": "0.0",
403
  "longitude": "0.0",
404
  "map_link": "",
405
+ "adresse": "Adidogomé Logoté, à 400m du carrefour Logoté sur la route menant au quartier Lankouvi"
406
  }
407
  ]
main.py ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from typing import TypedDict, Literal
3
+ from dotenv import load_dotenv
4
+
5
+ from langchain_groq import ChatGroq
6
+ from langchain_core.messages import HumanMessage, SystemMessage
7
+ from langgraph.graph import StateGraph, END
8
+ from pydantic import BaseModel, Field
9
+
10
+ from tools.pharma_tools import get_nearly
11
+ from tools.hospitals_tools import find_hospitals
12
+
13
+ load_dotenv()
14
+
15
+ import json
16
+ from datetime import datetime
17
+ import os
18
+
19
+ def save_for_finetuning(user_message: str, intention: str, mot_cle: str):
20
+ """Sauvegarde l'interaction au format JSONL pour un futur fine-tuning."""
21
+
22
+ log_entry = {
23
+ "timestamp": datetime.now().isoformat(),
24
+ "messages": [
25
+ {"role": "user", "content": user_message},
26
+ {"role": "assistant", "content": f'{{"categorie": "{intention}", "mot_cle": "{mot_cle}"}}'}
27
+ ]
28
+ }
29
+
30
+ # Chemin vers le fichier de sauvegarde (dans ton dossier data)
31
+ os.makedirs("data", exist_ok=True)
32
+ log_file = "data/finetuning_dataset.jsonl"
33
+
34
+ with open(log_file, "a", encoding="utf-8") as f:
35
+ f.write(json.dumps(log_entry, ensure_ascii=False) + "\n")
36
+
37
+ # Definition de l'Etat
38
+ class GraphState(TypedDict):
39
+ user_message: str
40
+ user_lat: float
41
+ user_lon: float
42
+ intention: str
43
+ mot_cle: str
44
+ final_response: str
45
+
46
+ # 2. Définition du format de sortie
47
+ class RouterOutput(BaseModel):
48
+ categorie: Literal["ORIENTATION", "SPECIALISTE", "PHARMACIE", "INCONNU"] = Field(
49
+ description="Classer la demande dans l'une de ces catégories."
50
+ )
51
+ mot_cle: str = Field(
52
+ description="Le service (ex: maternité), la spécialité (ex: cardiologue) ou vide si pharmacie.",
53
+ default=""
54
+ )
55
+
56
+ # Initialisation du LLM
57
+ llm = ChatGroq(model="openai/gpt-oss-120b", temperature=0)
58
+ # On force le LLM à répondre avec notre structure Pydantic
59
+ router_llm = llm.with_structured_output(RouterOutput)
60
+
61
+ # --- LES NOEUDS DU GRAPHE (NODES) ---
62
+
63
+ def analyze_intent(state: GraphState):
64
+ """Analyse le message de l'utilisateur et détermine la route à prendre."""
65
+ prompt = f"""Tu es le routeur principal d'un assistant médical au Togo.
66
+ Analyse ce message et extrais l'intention et le mot clé utile.
67
+
68
+ RÈGLE ABSOLUE POUR LE MOT_CLE :
69
+ Si l'utilisateur cherche un spécialiste, le mot clé DOIT TOUJOURS être le nom du service médical exact (souvent en "ie" ou "logie"), car c'est ce format qui est dans la base de données.
70
+ Exemples stricts :
71
+ - "pédiatre" ou "enfant" -> "pédiatrie"
72
+ - "cardiologue" -> "cardiologie"
73
+ - "ophtalmo" -> "ophtalmologie"
74
+ - "chirurgien" -> "chirurgie"
75
+ - "gynéco" ou "accoucher" -> "maternité"
76
+
77
+ Message : {state["user_message"]}"""
78
+
79
+ result = router_llm.invoke([SystemMessage(content=prompt)])
80
+
81
+ save_for_finetuning(state["user_message"], result.categorie, result.mot_cle)
82
+
83
+ return {"intention": result.categorie, "mot_cle": result.mot_cle}
84
+
85
+ def route_to_pharmacy(state: GraphState):
86
+ """Gère la recherche de pharmacies."""
87
+ response = get_nearly.invoke({
88
+ "user_lat": state["user_lat"],
89
+ "user_lon": state["user_lon"]
90
+ })
91
+
92
+ return {"final_response": response}
93
+
94
+ def route_to_orientation(state: GraphState):
95
+ """Gère l'orientation (rayon 20km)."""
96
+ response = find_hospitals.invoke({
97
+ "user_lat": state["user_lat"],
98
+ "user_lon": state["user_lon"],
99
+ "service_requis": state["mot_cle"],
100
+ "is_specialist": False
101
+ })
102
+ return {"final_response": response}
103
+
104
+ def route_to_specialist(state: GraphState):
105
+ """Gère la recherche de spécialiste."""
106
+ response = find_hospitals.invoke({
107
+ "user_lat": state["user_lat"],
108
+ "user_lon": state["user_lon"],
109
+ "service_requis": state["mot_cle"],
110
+ "is_specialist": True
111
+ })
112
+ return {"final_response": response}
113
+
114
+ # --- LA LOGIQUE DE ROUTAGE CONDITIONNEL (EDGES) ---
115
+
116
+ def decide_next_node(state: GraphState):
117
+ """Détermine le prochain nœud en fonction de l'intention."""
118
+ if state["intention"] == "PHARMACIE":
119
+ return "pharmacy_node"
120
+ elif state["intention"] == "SPECIALISTE":
121
+ return "specialist_node"
122
+ elif state["intention"] == "ORIENTATION":
123
+ return "orientation_node"
124
+ else:
125
+ return END
126
+
127
+ # --- CONSTRUCTION DU GRAPHE ---
128
+
129
+ workflow = StateGraph(GraphState)
130
+
131
+ # Ajout des nœuds
132
+ workflow.add_node("router_node", analyze_intent)
133
+ workflow.add_node("pharmacy_node", route_to_pharmacy)
134
+ workflow.add_node("orientation_node", route_to_orientation)
135
+ workflow.add_node("specialist_node", route_to_specialist)
136
+
137
+ # Le point d'entrée est toujours le routeur
138
+ workflow.set_entry_point("router_node")
139
+
140
+ # Ajout des conditions (Depuis le routeur, vers où aller ?)
141
+ workflow.add_conditional_edges(
142
+ "router_node",
143
+ decide_next_node,
144
+ {
145
+ "pharmacy_node": "pharmacy_node",
146
+ "specialist_node": "specialist_node",
147
+ "orientation_node": "orientation_node",
148
+ END: END
149
+ }
150
+ )
151
+
152
+ # Tous les nœuds d'action mènent à la fin
153
+ workflow.add_edge("pharmacy_node", END)
154
+ workflow.add_edge("orientation_node", END)
155
+ workflow.add_edge("specialist_node", END)
156
+
157
+ # Compilation du graphe
158
+ app = workflow.compile()
159
+
160
+ # --- TEST DU SYSTÈME ---
161
+ if __name__ == "__main__":
162
+ test_lat = 6.1725
163
+ test_lon = 1.2138
164
+
165
+ message_test = "j'ai tres mal au pieds "
166
+
167
+ print(f"Message utilisateur : {message_test}")
168
+
169
+ inputs = {
170
+ "user_message": message_test,
171
+ "user_lat": test_lat,
172
+ "user_lon": test_lon
173
+ }
174
+
175
+ result = app.invoke(inputs)
176
+
177
+ print("\n--- RÉSULTAT DU ROUTAGE ---")
178
+ print(f"Intention détectée : {result.get('intention')}")
179
+ print(f"Mot clé extrait : {result.get('mot_cle')}")
180
+ print(f"Réponse finale :\n{result.get('final_response')}")
requirements.txt CHANGED
@@ -7,4 +7,8 @@ langchain_core
7
  langchain_groq
8
  langchain_ollama
9
  requests
10
- pyshorteners
 
 
 
 
 
7
  langchain_groq
8
  langchain_ollama
9
  requests
10
+ pyshorteners
11
+ psycopg2-binary
12
+ uvicorn
13
+ pydantic
14
+ python-multipart
tools/__pycache__/hospitals_tools.cpython-312.pyc ADDED
Binary file (3.35 kB). View file
 
tools/__pycache__/pharma_tools.cpython-312.pyc CHANGED
Binary files a/tools/__pycache__/pharma_tools.cpython-312.pyc and b/tools/__pycache__/pharma_tools.cpython-312.pyc differ
 
tools/__pycache__/transcription.cpython-312.pyc ADDED
Binary file (950 Bytes). View file
 
tools/emergency_tools.py DELETED
File without changes
tools/hospitals_tools.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import psycopg2
3
+ from dotenv import load_dotenv
4
+ from langchain.tools import tool
5
+
6
+ # Connexion a la db
7
+ load_dotenv()
8
+
9
+ def get_db_connection():
10
+ db_url = os.getenv("DB_URL")
11
+ if not db_url:
12
+ raise ValueError("L'URL de la base de données RENDER_DB_URL est introuvable dans le .env")
13
+ return psycopg2.connect(db_url)
14
+
15
+ @tool
16
+ def find_hospitals(user_lat: float, user_lon: float, service_requis: str, is_specialist: bool = False):
17
+ """
18
+ Cherche les 5 hôpitaux les plus proches avec lits disponibles, sans limite de distance.
19
+ """
20
+ conn = get_db_connection()
21
+ cursor = conn.cursor()
22
+
23
+ # Requête unique et propre : on calcule la distance, on filtre par service/lits,
24
+ # on trie par proximité et on limite à 5.
25
+ query = """
26
+ SELECT h.name, h.address, h.phone,
27
+ (6371 * acos(cos(radians(%s)) * cos(radians(h.latitude)) * cos(radians(h.longitude) - radians(%s)) +
28
+ sin(radians(%s)) * sin(radians(h.latitude)))) AS distance_reelle,
29
+ h.latitude,
30
+ h.longitude
31
+ FROM structures h
32
+ WHERE EXISTS (
33
+ SELECT 1 FROM services s
34
+ WHERE s.structure_id = h.id
35
+ AND s.name ILIKE %s
36
+ AND s.total_beds >= 2
37
+ )
38
+ ORDER BY distance_reelle ASC
39
+ LIMIT 5;
40
+ """
41
+
42
+ def executer_recherche(mot_cle):
43
+ # On passe systématiquement les 4 paramètres requis par la requête ci-dessus
44
+ cursor.execute(query, (user_lat, user_lon, user_lat, f"%{mot_cle}%"))
45
+ return cursor.fetchall()
46
+
47
+ try:
48
+ # 3. On tente d'abord de chercher le service demandé
49
+ resultats_recherche = executer_recherche(service_requis)
50
+
51
+ # 4. GESTION DU REPLI
52
+ if not resultats_recherche:
53
+ resultats_fallback = executer_recherche("général")
54
+
55
+ if not resultats_fallback:
56
+ return "Aucun médecin généraliste trouvé à proximité."
57
+
58
+ resultats_finaux = resultats_fallback
59
+
60
+ else:
61
+ # Si on a trouvé le spécialiste
62
+ resultats_finaux = resultats_recherche
63
+
64
+ # 5. Boucle d'affichage
65
+ resultats_json = []
66
+
67
+ for row in resultats_finaux:
68
+ resultats_json.append({
69
+ "name": row[0],
70
+ "address": row[1],
71
+ "phone": row[2],
72
+ "distance": round(row[3], 2),
73
+ "map_link": f"https://www.google.com/maps/dir/?api=1&origin={user_lat},{user_lon}&destination={row[4]},{row[5]}"
74
+ })
75
+ return resultats_json
76
+
77
+ except Exception as e:
78
+ return f"[ERROR] Erreur base de données : {e}"
79
+ finally:
80
+ cursor.close()
81
+ conn.close()
tools/pharma_tools.py CHANGED
@@ -94,15 +94,21 @@ def get_nearly(user_lat, user_lon, fichier_json=CACHE_FILE_PATH):
94
  else:
95
  phar['distance_reelle'] = float('inf') # Trop loin si pas de GPS
96
 
97
- top_3 = sorted(pharmacies, key=lambda x: x['distance_reelle'])[:3]
98
-
99
- response_txt = ""
100
- for p in top_3:
101
- response_txt += f"\n - {p['nom']} \n {p['quartier']} \n {p['adresse']} \n {p['contacts']} \n {p['distance_reelle']} Km \n {p['map_link']} \n"
102
- return response_txt
 
 
 
 
 
 
103
 
104
  except FileNotFoundError:
105
- return "[ERROR] : JSON files does not exist"
106
  except Exception as e:
107
- return f"[ERROR] : {e}"
108
 
 
94
  else:
95
  phar['distance_reelle'] = float('inf') # Trop loin si pas de GPS
96
 
97
+ top_5 = sorted(pharmacies, key=lambda x: x['distance_reelle'])[:5]
98
+
99
+ resultats_json = []
100
+ for p in top_5:
101
+ resultats_json.append({
102
+ "name": p.get('nom', 'N/A'),
103
+ "address": f"{p.get('quartier', '')} - {p.get('adresse', '')}",
104
+ "phone": p.get('contacts', 'N/A'),
105
+ "distance": p['distance_reelle'],
106
+ "map_link": p.get('map_link', '')
107
+ })
108
+ return resultats_json
109
 
110
  except FileNotFoundError:
111
+ return {"error": "Le fichier JSON des pharmacies est introuvable."}
112
  except Exception as e:
113
+ return {"error": str(e)}
114
 
tools/prompts.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ router_prompt = """
2
+ TU ES : Le routeur principal de NOVA HEALTH.
3
+ TON RÔLE : Analyser la demande de l'utilisateur et la classer dans l'une des 3 catégories suivantes :
4
+ 1. "ORIENTATION" : L'utilisateur décrit une situation (femme enceinte, enfant malade, accident).
5
+ 2. "SPECIALISTE" : L'utilisateur cherche explicitement une spécialité médicale (cardiologue, ophtalmologue...).
6
+ 3. "PHARMACIE" : L'utilisateur cherche une pharmacie de garde ou des médicaments.
7
+
8
+ FORMAT DE SORTIE OBLIGATOIRE (JSON pur) :
9
+ {
10
+ "categorie": "ORIENTATION" | "SPECIALISTE" | "PHARMACIE",
11
+ "mot_cle": "maternité" | "pédiatrie" | "cardiologie" | null (selon le besoin extrait)
12
+ }
13
+ """
tools/transcription.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from groq import Groq
2
+ import os
3
+ from dotenv import load_dotenv
4
+
5
+ load_dotenv()
6
+
7
+ def transcribe_audio(audio_file_path):
8
+ client = Groq(api_key=os.getenv("GROQ_API_KEY"))
9
+
10
+ with open(audio_file_path, "rb") as file:
11
+ transcription = client.audio.transcriptions.create(
12
+ file=(audio_file_path, file.read()),
13
+ model="whisper-large-v3",
14
+ response_format="text", # "json"
15
+ language="fr"
16
+ )
17
+ return transcription