Ali2206 commited on
Commit
f2d2b0c
Β·
verified Β·
1 Parent(s): 6f7b230

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +125 -65
app.py CHANGED
@@ -5,14 +5,16 @@ from api import api_router
5
  import gradio as gr
6
  import requests
7
  import logging
 
8
 
 
9
  logging.basicConfig(level=logging.DEBUG)
10
  logger = logging.getLogger(__name__)
11
  logger.debug("Initializing application")
12
 
13
  app = FastAPI()
14
 
15
- # CORS
16
  app.add_middleware(
17
  CORSMiddleware,
18
  allow_origins=["*"],
@@ -23,6 +25,68 @@ app.add_middleware(
23
 
24
  app.include_router(api_router)
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  @app.get("/")
27
  def root():
28
  logger.debug("Root endpoint accessed")
@@ -36,13 +100,6 @@ async def redirect_login(request: Request):
36
 
37
  # Admin authentication logic
38
  def authenticate_admin(email: str = None, password: str = None):
39
- """
40
- Authenticate admin user with predefined email and password.
41
- In a production environment, this should use secure password hashing and a database.
42
- """
43
- ADMIN_EMAIL = "yakdhanali97@gmail.com"
44
- ADMIN_PASSWORD = "123456" # In production, hash this password and compare securely
45
-
46
  if email != ADMIN_EMAIL or password != ADMIN_PASSWORD:
47
  logger.warning(f"Failed admin login attempt with email: {email}")
48
  raise HTTPException(status_code=401, detail="Unauthorized: Invalid email or password")
@@ -50,59 +107,54 @@ def authenticate_admin(email: str = None, password: str = None):
50
  logger.info(f"Admin authenticated successfully: {email}")
51
  return True
52
 
53
- # Gradio doctor creation logic
54
- BACKEND_URL = "https://rocketfarmstudios-cps-api.hf.space"
55
-
56
- # Get admin token by logging in to the auth Space
57
- def get_admin_token():
58
- """
59
- Authenticate with the auth Space to get a JWT token for admin requests.
60
- """
61
- login_payload = {
62
- "username": "yakdhanali97@gmail.com",
63
- "password": "123456",
64
- "device_token": "admin-device-token" # Replace with a valid device token if required
65
- }
66
- try:
67
- res = requests.post(f"{BACKEND_URL}/auth/login", json=login_payload)
68
- if res.status_code == 200:
69
- token = res.json().get("access_token")
70
- logger.info("Successfully obtained admin token")
71
- return token
72
- else:
73
- logger.error(f"Failed to obtain admin token: {res.status_code} - {res.text}")
74
- raise Exception("Failed to obtain admin token")
75
- except Exception as e:
76
- logger.error(f"Error obtaining admin token: {str(e)}")
77
- raise
78
-
79
- # Store the admin token globally (in production, consider refreshing this token periodically)
80
- try:
81
- ADMIN_TOKEN = get_admin_token()
82
- except Exception as e:
83
- logger.critical("Could not initialize admin token, application startup failed")
84
- raise
85
-
86
  def create_doctor(full_name, email, matricule, password, specialty):
87
- payload = {
88
- "full_name": full_name,
89
- "email": email,
90
- "license_number": matricule,
91
- "password": password,
92
- "specialty": specialty,
93
- }
94
- headers = {
95
- "Authorization": f"Bearer {ADMIN_TOKEN}"
96
- }
97
  try:
98
- res = requests.post(f"{BACKEND_URL}/auth/admin/doctors", json=payload, headers=headers)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  if res.status_code == 201:
100
  return "βœ… Doctor created successfully!"
101
- return f"❌ {res.json().get('detail', 'Error occurred')}"
102
- except Exception as e:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  return f"❌ Network Error: {str(e)}"
 
 
104
 
105
- # Define Gradio interface
106
  admin_ui = gr.Blocks(css="""
107
  .gradio-container {
108
  background-color: #1A1B1F;
@@ -121,7 +173,7 @@ admin_ui = gr.Blocks(css="""
121
 
122
  with admin_ui:
123
  gr.Markdown("<div class='title-text'>πŸ‘¨β€βš•οΈ Doctor Account Creator</div>")
124
- gr.Markdown("<div class='description-text'>Admins can register new doctors using this secure panel. Generated at 10:09 PM CET on Sunday, May 25, 2025.</div>")
125
 
126
  with gr.Column():
127
  full_name = gr.Textbox(label="Full Name", placeholder="e.g. Dr. Sarah Hopkins")
@@ -129,8 +181,9 @@ with admin_ui:
129
  matricule = gr.Textbox(label="Matricule", placeholder="e.g. DOC-1234")
130
  specialty = gr.Dropdown(
131
  label="Specialty",
132
- choices=["Cardiology", "Neurology", "Pediatrics", "Oncology", "General Practice", "Psychiatry", "Dermatology", "Orthopedics"],
133
- value="Cardiology"
 
134
  )
135
  password = gr.Textbox(label="Password", type="password", placeholder="Secure password")
136
  submit_btn = gr.Button("Create Doctor Account")
@@ -142,22 +195,29 @@ with admin_ui:
142
  outputs=output
143
  )
144
 
145
- # Mount Gradio interface at startup (unprotected for now, authentication handled by route)
146
  app = gr.mount_gradio_app(app, admin_ui, path="/admin-auth")
147
 
148
- # Authentication route to redirect to /admin-auth with credentials
149
  @app.get("/admin")
150
  async def admin_dashboard(email: str = None, password: str = None, response: Response = None):
151
- logger.debug("Admin dashboard accessed with email and password")
152
  try:
153
  authenticate_admin(email, password)
154
- # Redirect to the mounted Gradio interface
155
  return RedirectResponse(url="/admin-auth", status_code=307)
156
  except HTTPException as e:
157
  response.status_code = 401
158
- return HTMLResponse(content="<h1>401 Unauthorized</h1><p>Invalid email or password. Please use: email=yakdhanali97@gmail.com&password=123456</p>")
 
 
 
 
 
 
 
 
159
 
160
  if __name__ == "__main__":
161
- logger.debug("Running main block")
162
  import uvicorn
163
- uvicorn.run(app, host="0.0.0.0", port=7860) # For local testing
 
5
  import gradio as gr
6
  import requests
7
  import logging
8
+ import time
9
 
10
+ # Configure logging
11
  logging.basicConfig(level=logging.DEBUG)
12
  logger = logging.getLogger(__name__)
13
  logger.debug("Initializing application")
14
 
15
  app = FastAPI()
16
 
17
+ # CORS Configuration
18
  app.add_middleware(
19
  CORSMiddleware,
20
  allow_origins=["*"],
 
25
 
26
  app.include_router(api_router)
27
 
28
+ # Constants
29
+ BACKEND_URL = "https://rocketfarmstudios-cps-api.hf.space"
30
+ ADMIN_EMAIL = "yakdhanali97@gmail.com"
31
+ ADMIN_PASSWORD = "123456"
32
+ MAX_TOKEN_RETRIES = 3
33
+ TOKEN_RETRY_DELAY = 2 # seconds
34
+
35
+ # Global token storage with refresh capability
36
+ class TokenManager:
37
+ def __init__(self):
38
+ self.token = None
39
+ self.last_obtained = 0
40
+ self.token_expiry = 3600 # 1 hour default expiry
41
+
42
+ def get_token(self, force_refresh=False):
43
+ current_time = time.time()
44
+
45
+ if not force_refresh and self.token and (current_time - self.last_obtained) < self.token_expiry:
46
+ return self.token
47
+
48
+ for attempt in range(MAX_TOKEN_RETRIES):
49
+ try:
50
+ login_payload = {
51
+ "username": ADMIN_EMAIL,
52
+ "password": ADMIN_PASSWORD,
53
+ "device_token": "admin-device-token"
54
+ }
55
+
56
+ logger.debug(f"Attempting to obtain admin token (attempt {attempt + 1})")
57
+ res = requests.post(
58
+ f"{BACKEND_URL}/auth/login",
59
+ json=login_payload,
60
+ timeout=10
61
+ )
62
+
63
+ if res.status_code == 200:
64
+ token_data = res.json()
65
+ self.token = token_data.get("access_token")
66
+ if not self.token:
67
+ raise Exception("No access_token in response")
68
+
69
+ self.last_obtained = current_time
70
+ # Get expiry from token if available, otherwise use default
71
+ self.token_expiry = token_data.get("expires_in", 3600)
72
+ logger.info("Successfully obtained admin token")
73
+ return self.token
74
+
75
+ logger.error(f"Token request failed: {res.status_code} - {res.text}")
76
+ if res.status_code == 401:
77
+ raise Exception("Invalid admin credentials")
78
+
79
+ except requests.exceptions.RequestException as e:
80
+ logger.error(f"Network error during token fetch: {str(e)}")
81
+ if attempt < MAX_TOKEN_RETRIES - 1:
82
+ time.sleep(TOKEN_RETRY_DELAY)
83
+ continue
84
+
85
+ raise Exception("Failed to obtain admin token after multiple attempts")
86
+
87
+ token_manager = TokenManager()
88
+
89
+ # Root endpoint
90
  @app.get("/")
91
  def root():
92
  logger.debug("Root endpoint accessed")
 
100
 
101
  # Admin authentication logic
102
  def authenticate_admin(email: str = None, password: str = None):
 
 
 
 
 
 
 
103
  if email != ADMIN_EMAIL or password != ADMIN_PASSWORD:
104
  logger.warning(f"Failed admin login attempt with email: {email}")
105
  raise HTTPException(status_code=401, detail="Unauthorized: Invalid email or password")
 
107
  logger.info(f"Admin authenticated successfully: {email}")
108
  return True
109
 
110
+ # Doctor creation with token handling
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  def create_doctor(full_name, email, matricule, password, specialty):
 
 
 
 
 
 
 
 
 
 
112
  try:
113
+ token = token_manager.get_token()
114
+
115
+ payload = {
116
+ "full_name": full_name,
117
+ "email": email,
118
+ "license_number": matricule,
119
+ "password": password,
120
+ "specialty": specialty,
121
+ }
122
+ headers = {
123
+ "Authorization": f"Bearer {token}",
124
+ "Content-Type": "application/json"
125
+ }
126
+
127
+ res = requests.post(
128
+ f"{BACKEND_URL}/auth/admin/doctors",
129
+ json=payload,
130
+ headers=headers,
131
+ timeout=10
132
+ )
133
+
134
  if res.status_code == 201:
135
  return "βœ… Doctor created successfully!"
136
+ elif res.status_code == 401: # Token might be expired
137
+ logger.warning("Token expired, attempting refresh...")
138
+ token = token_manager.get_token(force_refresh=True)
139
+ headers["Authorization"] = f"Bearer {token}"
140
+ res = requests.post(
141
+ f"{BACKEND_URL}/auth/admin/doctors",
142
+ json=payload,
143
+ headers=headers,
144
+ timeout=10
145
+ )
146
+ if res.status_code == 201:
147
+ return "βœ… Doctor created successfully!"
148
+
149
+ error_detail = res.json().get('detail', 'Unknown error occurred')
150
+ return f"❌ Error: {error_detail} (Status: {res.status_code})"
151
+
152
+ except requests.exceptions.RequestException as e:
153
  return f"❌ Network Error: {str(e)}"
154
+ except Exception as e:
155
+ return f"❌ System Error: {str(e)}"
156
 
157
+ # Gradio interface
158
  admin_ui = gr.Blocks(css="""
159
  .gradio-container {
160
  background-color: #1A1B1F;
 
173
 
174
  with admin_ui:
175
  gr.Markdown("<div class='title-text'>πŸ‘¨β€βš•οΈ Doctor Account Creator</div>")
176
+ gr.Markdown("<div class='description-text'>Admins can register new doctors using this secure panel</div>")
177
 
178
  with gr.Column():
179
  full_name = gr.Textbox(label="Full Name", placeholder="e.g. Dr. Sarah Hopkins")
 
181
  matricule = gr.Textbox(label="Matricule", placeholder="e.g. DOC-1234")
182
  specialty = gr.Dropdown(
183
  label="Specialty",
184
+ choices=["Cardiology", "Neurology", "Pediatrics", "Oncology",
185
+ "General Practice", "Psychiatry", "Dermatology", "Orthopedics"],
186
+ value="General Practice"
187
  )
188
  password = gr.Textbox(label="Password", type="password", placeholder="Secure password")
189
  submit_btn = gr.Button("Create Doctor Account")
 
195
  outputs=output
196
  )
197
 
198
+ # Mount Gradio interface
199
  app = gr.mount_gradio_app(app, admin_ui, path="/admin-auth")
200
 
201
+ # Admin dashboard route
202
  @app.get("/admin")
203
  async def admin_dashboard(email: str = None, password: str = None, response: Response = None):
204
+ logger.debug("Admin dashboard accessed")
205
  try:
206
  authenticate_admin(email, password)
 
207
  return RedirectResponse(url="/admin-auth", status_code=307)
208
  except HTTPException as e:
209
  response.status_code = 401
210
+ return HTMLResponse(content="""
211
+ <h1>401 Unauthorized</h1>
212
+ <p>Invalid email or password.</p>
213
+ <p>Please use the following credentials:</p>
214
+ <ul>
215
+ <li>Email: yakdhanali97@gmail.com</li>
216
+ <li>Password: 123456</li>
217
+ </ul>
218
+ """)
219
 
220
  if __name__ == "__main__":
221
+ logger.info("Starting application")
222
  import uvicorn
223
+ uvicorn.run(app, host="0.0.0.0", port=7860)