Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, Request, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import RedirectResponse, JSONResponse | |
| from fastapi.exceptions import RequestValidationError | |
| from api import api_router | |
| import gradio as gr | |
| import requests | |
| import logging | |
| import os | |
| from datetime import datetime | |
| # Configure logging | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format='%(asctime)s - %(levelname)s - %(name)s - %(message)s', | |
| handlers=[ | |
| logging.StreamHandler(), | |
| logging.FileHandler('app.log') | |
| ] | |
| ) | |
| logger = logging.getLogger(__name__) | |
| app = FastAPI( | |
| title="Medical EHR System", | |
| description="Electronic Health Records Management API", | |
| version="1.0.0", | |
| docs_url="/docs", | |
| redoc_url="/redoc" | |
| ) | |
| # CORS Configuration | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| expose_headers=["*"] | |
| ) | |
| # Include API routes | |
| app.include_router(api_router, prefix="/api/v1") | |
| async def root(): | |
| logger.info("Root endpoint accessed") | |
| return {"message": "π FastAPI with MongoDB + JWT is running", "status": "healthy"} | |
| async def redirect_login(request: Request): | |
| logger.info(f"Redirecting /login to /auth/login from {request.client.host}") | |
| return RedirectResponse(url="/auth/login", status_code=status.HTTP_307_TEMPORARY_REDIRECT) | |
| async def validation_exception_handler(request: Request, exc: RequestValidationError): | |
| logger.error(f"Validation error: {exc.errors()}") | |
| return JSONResponse( | |
| status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, | |
| content={"detail": exc.errors(), "body": exc.body}, | |
| ) | |
| async def http_exception_handler(request: Request, exc: HTTPException): | |
| logger.error(f"HTTP error: {exc.detail}") | |
| return JSONResponse( | |
| status_code=exc.status_code, | |
| content={"detail": exc.detail}, | |
| headers=exc.headers | |
| ) | |
| async def general_exception_handler(request: Request, exc: Exception): | |
| logger.error(f"Unhandled exception: {str(exc)}", exc_info=True) | |
| return JSONResponse( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| content={"detail": "Internal server error"}, | |
| ) | |
| # Gradio Interface Configuration | |
| BACKEND_URL = os.getenv("BACKEND_URL", "http://localhost:8000") | |
| def create_doctor(full_name: str, email: str, matricule: str, password: str, specialty: str): | |
| try: | |
| payload = { | |
| "full_name": full_name, | |
| "email": email, | |
| "license_number": matricule, | |
| "password": password, | |
| "specialty": specialty, | |
| } | |
| logger.info(f"Attempting to create doctor: {email}") | |
| response = requests.post( | |
| f"{BACKEND_URL}/auth/admin/doctors", | |
| json=payload, | |
| headers={"Content-Type": "application/json"}, | |
| timeout=10 | |
| ) | |
| if response.status_code == 201: | |
| logger.info(f"Successfully created doctor: {email}") | |
| return "β Doctor created successfully!" | |
| else: | |
| error_msg = response.json().get("detail", "Unknown error occurred") | |
| logger.error(f"Failed to create doctor {email}: {error_msg}") | |
| return f"β Error: {error_msg}" | |
| except requests.exceptions.RequestException as e: | |
| logger.error(f"Network error during doctor creation: {str(e)}") | |
| return f"β Network Error: {str(e)}" | |
| except Exception as e: | |
| logger.error(f"Unexpected error during doctor creation: {str(e)}") | |
| return f"β Unexpected Error: {str(e)}" | |
| def setup_gradio_interface(): | |
| with gr.Blocks( | |
| title="Doctor Management Portal", | |
| css=""" | |
| .gradio-container { max-width: 800px; margin: 0 auto; } | |
| .success { color: #4CAF50; } | |
| .error { color: #F44336; } | |
| """ | |
| ) as interface: | |
| gr.Markdown("# π¨ββοΈ Doctor Account Management") | |
| with gr.Row(): | |
| with gr.Column(): | |
| full_name = gr.Textbox(label="Full Name", placeholder="Dr. John Smith") | |
| email = gr.Textbox(label="Email", placeholder="doctor@hospital.org") | |
| matricule = gr.Textbox(label="License Number", placeholder="MD-12345") | |
| specialty = gr.Dropdown( | |
| label="Specialty", | |
| choices=["Cardiology", "Neurology", "Pediatrics", "General Practice"], | |
| value="General Practice" | |
| ) | |
| password = gr.Textbox(label="Password", type="password") | |
| submit_btn = gr.Button("Create Doctor Account", variant="primary") | |
| with gr.Column(): | |
| output = gr.Textbox(label="Result", interactive=False) | |
| submit_btn.click( | |
| fn=create_doctor, | |
| inputs=[full_name, email, matricule, specialty, password], | |
| outputs=output | |
| ) | |
| return interface | |
| # Mount Gradio interface | |
| gradio_ui = setup_gradio_interface() | |
| app = gr.mount_gradio_app(app, gradio_ui, path="/admin") | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run( | |
| app, | |
| host="0.0.0.0", | |
| port=int(os.getenv("PORT", 8000)), | |
| log_level="info", | |
| reload=True | |
| ) |