YchKhan commited on
Commit
bd5c958
·
verified ·
1 Parent(s): 21974f1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -20
app.py CHANGED
@@ -1,5 +1,6 @@
1
  import asyncio
2
- from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Request
 
3
  from fastapi.responses import HTMLResponse
4
  from fastapi.staticfiles import StaticFiles
5
  from fastapi.middleware.cors import CORSMiddleware
@@ -11,13 +12,12 @@ import uvicorn
11
  app = FastAPI()
12
 
13
  # Configurer CORS pour autoriser toutes les origines
14
- # Permet à n'importe quel site web d'appeler votre API
15
  app.add_middleware(
16
  CORSMiddleware,
17
- allow_origins=["*"], # Autorise toutes les origines
18
  allow_credentials=True,
19
- allow_methods=["*"], # Autorise toutes les méthodes (GET, POST, etc.)
20
- allow_headers=["*"], # Autorise tous les en-têtes
21
  )
22
 
23
  # Monter un répertoire statique pour servir le fichier index.html
@@ -26,6 +26,7 @@ app.mount("/static", StaticFiles(directory="static"), name="static")
26
  class MockRequest(BaseModel):
27
  """Définit la structure attendue pour le corps de la requête POST."""
28
  parameter: str
 
29
 
30
  class ConnectionManager:
31
  """Gère les connexions WebSocket actives."""
@@ -53,7 +54,7 @@ class ConnectionManager:
53
  await websocket.send_text(message)
54
  # Créer un Future pour attendre la réponse
55
  future = asyncio.get_event_loop().create_future()
56
- # Utilise l'identifiant du client comme clé, bien que simple, c'est plus robuste
57
  client_id = str(id(websocket))
58
  self.response_futures[client_id] = future
59
  return future
@@ -61,6 +62,15 @@ class ConnectionManager:
61
 
62
  manager = ConnectionManager()
63
 
 
 
 
 
 
 
 
 
 
64
 
65
  @app.get("/", response_class=HTMLResponse)
66
  async def root():
@@ -71,32 +81,38 @@ async def root():
71
  except FileNotFoundError:
72
  raise HTTPException(status_code=404, detail="index.html not found")
73
 
74
-
75
  @app.post("/v1/mock")
76
  async def mock_endpoint(payload: MockRequest):
77
  """
78
- Endpoint API qui prend un string, le transmet via WebSocket,
79
- attend une réponse et la retourne.
80
  """
81
  try:
82
- # Récupérer les données JSON du corps de la requête
83
- # data = await request.json()
84
  input_string = payload.parameter
 
 
 
 
 
 
 
 
 
 
 
85
 
86
  if input_string is None:
87
- return {"error": "Le paramètre 'parameter' est manquant."}
88
 
89
- print(f"Endpoint /v1/mock appelé avec: '{input_string}'")
90
-
91
  if not manager.active_connections:
92
- return {"error": "Aucun client WebSocket n'est connecté."}
93
 
94
  # Envoyer le message via WebSocket et obtenir un "future" pour la réponse
95
  print("Envoi du message au client WebSocket...")
96
  response_future = await manager.broadcast(input_string)
97
 
98
  if response_future is None:
99
- return {"error": "Échec de la diffusion du message."}
100
 
101
  try:
102
  # Attendre la réponse du client WebSocket avec un timeout de 60 secondes
@@ -106,12 +122,14 @@ async def mock_endpoint(payload: MockRequest):
106
 
107
  except asyncio.TimeoutError:
108
  print("Timeout: Aucune réponse du client WebSocket.")
109
- return {"error": "Timeout: Le client n'a pas répondu à temps."}
110
 
 
 
 
111
  except Exception as e:
112
  print(f"Erreur dans /v1/mock: {e}")
113
- return {"error": f"Une erreur interne est survenue: {str(e)}"}
114
-
115
 
116
  @app.websocket("/ws")
117
  async def websocket_endpoint(websocket: WebSocket):
@@ -136,6 +154,5 @@ async def websocket_endpoint(websocket: WebSocket):
136
  print(f"Erreur dans le WebSocket: {e}")
137
  manager.disconnect(websocket)
138
 
139
-
140
  if __name__ == "__main__":
141
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
  import asyncio
2
+ import os
3
+ from fastapi import FastAPI, WebSocket, WebSocketDisconnect, HTTPException
4
  from fastapi.responses import HTMLResponse
5
  from fastapi.staticfiles import StaticFiles
6
  from fastapi.middleware.cors import CORSMiddleware
 
12
  app = FastAPI()
13
 
14
  # Configurer CORS pour autoriser toutes les origines
 
15
  app.add_middleware(
16
  CORSMiddleware,
17
+ allow_origins=["*"],
18
  allow_credentials=True,
19
+ allow_methods=["*"],
20
+ allow_headers=["*"],
21
  )
22
 
23
  # Monter un répertoire statique pour servir le fichier index.html
 
26
  class MockRequest(BaseModel):
27
  """Définit la structure attendue pour le corps de la requête POST."""
28
  parameter: str
29
+ secret: str # Nouveau champ pour le secret
30
 
31
  class ConnectionManager:
32
  """Gère les connexions WebSocket actives."""
 
54
  await websocket.send_text(message)
55
  # Créer un Future pour attendre la réponse
56
  future = asyncio.get_event_loop().create_future()
57
+ # Utilise l'identifiant du client comme clé
58
  client_id = str(id(websocket))
59
  self.response_futures[client_id] = future
60
  return future
 
62
 
63
  manager = ConnectionManager()
64
 
65
+ def verify_secret(provided_secret: str) -> bool:
66
+ """Vérifie si le secret fourni correspond à celui de la variable d'environnement."""
67
+ expected_secret = os.getenv("API_SECRET")
68
+
69
+ if not expected_secret:
70
+ print("ATTENTION: Variable d'environnement API_SECRET non définie!")
71
+ return False
72
+
73
+ return provided_secret == expected_secret
74
 
75
  @app.get("/", response_class=HTMLResponse)
76
  async def root():
 
81
  except FileNotFoundError:
82
  raise HTTPException(status_code=404, detail="index.html not found")
83
 
 
84
  @app.post("/v1/mock")
85
  async def mock_endpoint(payload: MockRequest):
86
  """
87
+ Endpoint API qui prend un string et un secret, vérifie le secret,
88
+ puis transmet via WebSocket, attend une réponse et la retourne.
89
  """
90
  try:
 
 
91
  input_string = payload.parameter
92
+ provided_secret = payload.secret
93
+
94
+ # Vérification du secret AVANT tout traitement
95
+ if not verify_secret(provided_secret):
96
+ print(f"Tentative d'accès avec un secret invalide: '{provided_secret[:10]}...'")
97
+ raise HTTPException(
98
+ status_code=401,
99
+ detail="Secret invalide. Accès non autorisé."
100
+ )
101
+
102
+ print(f"Secret vérifié avec succès. Endpoint /v1/mock appelé avec: '{input_string}'")
103
 
104
  if input_string is None:
105
+ raise HTTPException(status_code=400, detail="Le paramètre 'parameter' est manquant.")
106
 
 
 
107
  if not manager.active_connections:
108
+ raise HTTPException(status_code=503, detail="Aucun client WebSocket n'est connecté.")
109
 
110
  # Envoyer le message via WebSocket et obtenir un "future" pour la réponse
111
  print("Envoi du message au client WebSocket...")
112
  response_future = await manager.broadcast(input_string)
113
 
114
  if response_future is None:
115
+ raise HTTPException(status_code=500, detail="Échec de la diffusion du message.")
116
 
117
  try:
118
  # Attendre la réponse du client WebSocket avec un timeout de 60 secondes
 
122
 
123
  except asyncio.TimeoutError:
124
  print("Timeout: Aucune réponse du client WebSocket.")
125
+ raise HTTPException(status_code=408, detail="Timeout: Le client n'a pas répondu à temps.")
126
 
127
+ except HTTPException:
128
+ # Re-lever les HTTPException sans les wrapper
129
+ raise
130
  except Exception as e:
131
  print(f"Erreur dans /v1/mock: {e}")
132
+ raise HTTPException(status_code=500, detail=f"Une erreur interne est survenue: {str(e)}")
 
133
 
134
  @app.websocket("/ws")
135
  async def websocket_endpoint(websocket: WebSocket):
 
154
  print(f"Erreur dans le WebSocket: {e}")
155
  manager.disconnect(websocket)
156
 
 
157
  if __name__ == "__main__":
158
  uvicorn.run(app, host="0.0.0.0", port=7860)