Ali2206 commited on
Commit
37ca855
·
verified ·
1 Parent(s): 23f156e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -34
app.py CHANGED
@@ -1,67 +1,88 @@
1
  from fastapi import FastAPI, Request, HTTPException, Response
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.responses import RedirectResponse, HTMLResponse
4
- from api import api_router
5
  import gradio as gr
6
- import requests
7
- import logging
8
- import time
9
  import aiohttp
10
  import asyncio
 
 
 
11
  from typing import Optional
 
12
 
13
  # Configure logging
14
- logging.basicConfig(level=logging.DEBUG)
 
 
 
15
  logger = logging.getLogger(__name__)
16
  logger.debug("Initializing application")
17
 
 
18
  app = FastAPI()
19
 
20
- # CORS Configuration
21
  app.add_middleware(
22
  CORSMiddleware,
23
- allow_origins=["*"],
24
  allow_credentials=True,
25
  allow_methods=["*"],
26
  allow_headers=["*"],
27
  )
28
 
29
- app.include_router(api_router)
 
30
 
31
- # Constants
32
- BACKEND_URL = "https://rocketfarmstudios-cps-api.hf.space"
33
- ADMIN_EMAIL = "yakdhanali97@gmail.com"
34
- ADMIN_PASSWORD = "123456"
35
  MAX_TOKEN_RETRIES = 3
36
  TOKEN_RETRY_DELAY = 2 # seconds
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
  class TokenManager:
39
  def __init__(self):
40
  self.token = None
41
  self.last_refresh = 0
42
- self.expires_in = 3600 # 1 hour default expiry
43
  self.lock = asyncio.Lock()
44
 
45
  async def _make_login_request(self) -> Optional[str]:
46
  try:
47
  async with aiohttp.ClientSession() as session:
 
48
  async with session.post(
49
  f"{BACKEND_URL}/auth/login",
50
- json={
51
- "username": ADMIN_EMAIL,
52
- "password": ADMIN_PASSWORD,
53
- "device_token": "admin-device-token"
54
- },
55
  timeout=10
56
  ) as response:
57
  if response.status == 200:
58
  data = await response.json()
59
- return data.get("access_token")
 
 
 
 
60
  else:
61
  error = await response.text()
62
  logger.error(f"Login failed: {response.status} - {error}")
63
  return None
64
- except Exception as e:
65
  logger.error(f"Login request error: {str(e)}")
66
  return None
67
 
@@ -75,11 +96,11 @@ class TokenManager:
75
  logger.info("Successfully refreshed admin token")
76
  return token
77
 
78
- wait_time = min(5, (attempt + 1) * 2) # Exponential backoff with max 5s
79
  logger.warning(f"Attempt {attempt + 1} failed, retrying in {wait_time}s...")
80
  await asyncio.sleep(wait_time)
81
 
82
- raise Exception("Failed to obtain admin token after multiple attempts")
83
 
84
  async def get_token(self) -> str:
85
  if not self.token or (time.time() - self.last_refresh) > (self.expires_in - 60):
@@ -88,6 +109,9 @@ class TokenManager:
88
 
89
  token_manager = TokenManager()
90
 
 
 
 
91
  @app.get("/")
92
  def root():
93
  logger.debug("Root endpoint accessed")
@@ -106,17 +130,21 @@ def authenticate_admin(email: str = None, password: str = None):
106
  logger.info(f"Admin authenticated successfully: {email}")
107
  return True
108
 
109
- async def async_create_doctor(full_name, email, matricule, password, specialty):
110
  try:
 
 
 
 
111
  token = await token_manager.get_token()
112
 
113
- payload = {
114
- "full_name": full_name,
115
- "email": email,
116
- "license_number": matricule,
117
- "password": password,
118
- "specialty": specialty,
119
- }
120
  headers = {
121
  "Authorization": f"Bearer {token}",
122
  "Content-Type": "application/json"
@@ -125,7 +153,7 @@ async def async_create_doctor(full_name, email, matricule, password, specialty):
125
  async with aiohttp.ClientSession() as session:
126
  async with session.post(
127
  f"{BACKEND_URL}/auth/admin/doctors",
128
- json=payload,
129
  headers=headers,
130
  timeout=10
131
  ) as response:
@@ -137,23 +165,29 @@ async def async_create_doctor(full_name, email, matricule, password, specialty):
137
  headers["Authorization"] = f"Bearer {token}"
138
  async with session.post(
139
  f"{BACKEND_URL}/auth/admin/doctors",
140
- json=payload,
141
  headers=headers,
142
  timeout=10
143
  ) as retry_response:
144
  if retry_response.status == 201:
145
  return "✅ Doctor created successfully!"
 
 
146
 
147
  error_detail = await response.text()
148
  return f"❌ Error: {error_detail} (Status: {response.status})"
149
 
 
 
 
150
  except Exception as e:
151
  logger.error(f"Doctor creation failed: {str(e)}")
152
  return f"❌ System Error: {str(e)}"
153
 
154
- def sync_create_doctor(*args):
155
- return asyncio.run(async_create_doctor(*args))
156
 
 
157
  admin_ui = gr.Blocks(
158
  css="""
159
  .gradio-container {
@@ -218,11 +252,17 @@ async def admin_dashboard(email: str = None, password: str = None, response: Res
218
  <p>Invalid admin credentials</p>
219
  """)
220
 
 
 
 
 
 
221
  @app.on_event("startup")
222
  async def startup_event():
223
  """Initialize token but don't fail startup"""
224
  try:
225
  await token_manager.get_token()
 
226
  except Exception as e:
227
  logger.error(f"Initial token fetch failed: {str(e)}")
228
 
 
1
  from fastapi import FastAPI, Request, HTTPException, Response
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.responses import RedirectResponse, HTMLResponse
4
+ from pydantic import BaseModel
5
  import gradio as gr
 
 
 
6
  import aiohttp
7
  import asyncio
8
+ import logging
9
+ import time
10
+ import os
11
  from typing import Optional
12
+ from fastapi import APIRouter
13
 
14
  # Configure logging
15
+ logging.basicConfig(
16
+ level=logging.DEBUG,
17
+ format="%(asctime)s - %(levelname)s - %(name)s - %(message)s"
18
+ )
19
  logger = logging.getLogger(__name__)
20
  logger.debug("Initializing application")
21
 
22
+ # FastAPI app
23
  app = FastAPI()
24
 
25
+ # CORS Configuration (restrict in production)
26
  app.add_middleware(
27
  CORSMiddleware,
28
+ allow_origins=["http://localhost:7860", "https://your-production-domain.com"], # Update for production
29
  allow_credentials=True,
30
  allow_methods=["*"],
31
  allow_headers=["*"],
32
  )
33
 
34
+ # API Router (assuming this is defined elsewhere)
35
+ api_router = APIRouter()
36
 
37
+ # Constants (load from environment variables for security)
38
+ BACKEND_URL = os.getenv("BACKEND_URL", "https://rocketfarmstudios-cps-api.hf.space")
39
+ ADMIN_EMAIL = os.getenv("ADMIN_EMAIL", "yakdhanali97@gmail.com")
40
+ ADMIN_PASSWORD = os.getenv("ADMIN_PASSWORD", "123456")
41
  MAX_TOKEN_RETRIES = 3
42
  TOKEN_RETRY_DELAY = 2 # seconds
43
+ TOKEN_EXPIRY = 3600 # 1 hour default expiry
44
+
45
+ # Pydantic model for login payload
46
+ class LoginPayload(BaseModel):
47
+ username: str
48
+ password: str
49
+
50
+ # Pydantic model for doctor creation payload
51
+ class DoctorPayload(BaseModel):
52
+ full_name: str
53
+ email: str
54
+ license_number: str
55
+ password: str
56
+ specialty: str
57
 
58
  class TokenManager:
59
  def __init__(self):
60
  self.token = None
61
  self.last_refresh = 0
62
+ self.expires_in = TOKEN_EXPIRY
63
  self.lock = asyncio.Lock()
64
 
65
  async def _make_login_request(self) -> Optional[str]:
66
  try:
67
  async with aiohttp.ClientSession() as session:
68
+ payload = LoginPayload(username=ADMIN_EMAIL, password=ADMIN_PASSWORD)
69
  async with session.post(
70
  f"{BACKEND_URL}/auth/login",
71
+ json=payload.dict(),
 
 
 
 
72
  timeout=10
73
  ) as response:
74
  if response.status == 200:
75
  data = await response.json()
76
+ token = data.get("access_token")
77
+ if not token:
78
+ logger.error("No access_token in response")
79
+ return None
80
+ return token
81
  else:
82
  error = await response.text()
83
  logger.error(f"Login failed: {response.status} - {error}")
84
  return None
85
+ except aiohttp.ClientError as e:
86
  logger.error(f"Login request error: {str(e)}")
87
  return None
88
 
 
96
  logger.info("Successfully refreshed admin token")
97
  return token
98
 
99
+ wait_time = min(5, (attempt + 1) * TOKEN_RETRY_DELAY)
100
  logger.warning(f"Attempt {attempt + 1} failed, retrying in {wait_time}s...")
101
  await asyncio.sleep(wait_time)
102
 
103
+ raise HTTPException(status_code=500, detail="Failed to obtain admin token after multiple attempts")
104
 
105
  async def get_token(self) -> str:
106
  if not self.token or (time.time() - self.last_refresh) > (self.expires_in - 60):
 
109
 
110
  token_manager = TokenManager()
111
 
112
+ # Include API router
113
+ app.include_router(api_router)
114
+
115
  @app.get("/")
116
  def root():
117
  logger.debug("Root endpoint accessed")
 
130
  logger.info(f"Admin authenticated successfully: {email}")
131
  return True
132
 
133
+ async def async_create_doctor(full_name: str, email: str, license_number: str, specialty: str, password: str):
134
  try:
135
+ # Validate inputs
136
+ if not all([full_name, email, license_number, specialty, password]):
137
+ raise HTTPException(status_code=422, detail="All fields are required")
138
+
139
  token = await token_manager.get_token()
140
 
141
+ payload = DoctorPayload(
142
+ full_name=full_name,
143
+ email=email,
144
+ license_number=license_number,
145
+ password=password,
146
+ specialty=specialty
147
+ )
148
  headers = {
149
  "Authorization": f"Bearer {token}",
150
  "Content-Type": "application/json"
 
153
  async with aiohttp.ClientSession() as session:
154
  async with session.post(
155
  f"{BACKEND_URL}/auth/admin/doctors",
156
+ json=payload.dict(),
157
  headers=headers,
158
  timeout=10
159
  ) as response:
 
165
  headers["Authorization"] = f"Bearer {token}"
166
  async with session.post(
167
  f"{BACKEND_URL}/auth/admin/doctors",
168
+ json=payload.dict(),
169
  headers=headers,
170
  timeout=10
171
  ) as retry_response:
172
  if retry_response.status == 201:
173
  return "✅ Doctor created successfully!"
174
+ error_detail = await retry_response.text()
175
+ return f"❌ Error: {error_detail} (Status: {retry_response.status})"
176
 
177
  error_detail = await response.text()
178
  return f"❌ Error: {error_detail} (Status: {response.status})"
179
 
180
+ except HTTPException as e:
181
+ logger.error(f"Doctor creation failed: {str(e)}")
182
+ return f"❌ Error: {str(e)}"
183
  except Exception as e:
184
  logger.error(f"Doctor creation failed: {str(e)}")
185
  return f"❌ System Error: {str(e)}"
186
 
187
+ def sync_create_doctor(full_name: str, email: str, license_number: str, specialty: str, password: str):
188
+ return asyncio.run(async_create_doctor(full_name, email, license_number, specialty, password))
189
 
190
+ # Gradio UI
191
  admin_ui = gr.Blocks(
192
  css="""
193
  .gradio-container {
 
252
  <p>Invalid admin credentials</p>
253
  """)
254
 
255
+ @app.get("/admin-auth/gradio_api/queue/data")
256
+ async def gradio_queue_data(session_hash: str):
257
+ logger.debug(f"Gradio queue data accessed with session_hash: {session_hash}")
258
+ return {"status": "ok", "session_hash": session_hash}
259
+
260
  @app.on_event("startup")
261
  async def startup_event():
262
  """Initialize token but don't fail startup"""
263
  try:
264
  await token_manager.get_token()
265
+ logger.info("Initial token fetch successful")
266
  except Exception as e:
267
  logger.error(f"Initial token fetch failed: {str(e)}")
268