Spaces:
Runtime error
Runtime error
| # File: src/booking_api.py | |
| # Purpose: Mock hospital booking API (FastAPI) that processes and confirms appointments | |
| import json | |
| import uuid | |
| import random | |
| from datetime import datetime | |
| from pathlib import Path | |
| from fastapi import FastAPI, HTTPException | |
| from pydantic import BaseModel | |
| import sys | |
| sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) | |
| from config import AVAILABLE_SLOTS, DEPARTMENTS, BOOKING_LOG_PATH | |
| app = FastAPI(title="Hospital Booking API", version="1.0") | |
| # In-memory store simulating a database | |
| _booked_slots: dict[str, list[str]] = {} # { "department::date": [slot1, slot2] } | |
| class BookingRequest(BaseModel): | |
| patient_name: str | |
| department: str | |
| date: str # YYYY-MM-DD | |
| slot: str | |
| class BookingResponse(BaseModel): | |
| success: bool | |
| appointment_id: str | None = None | |
| reason: str | None = None | |
| patient_name: str | None = None | |
| department: str | None = None | |
| date: str | None = None | |
| slot: str | None = None | |
| doctor: str | None = None | |
| def _log_booking(record: dict): | |
| """Append booking attempt to JSONL log for audit trail.""" | |
| BOOKING_LOG_PATH.parent.mkdir(parents=True, exist_ok=True) | |
| with open(BOOKING_LOG_PATH, "a") as f: | |
| f.write(json.dumps(record) + "\n") | |
| def book_appointment(req: BookingRequest) -> BookingResponse: | |
| """ | |
| Book an appointment. Returns a confirmed appointment_id on success | |
| or an error reason on failure. | |
| This endpoint simulates real constraints: | |
| - Slot must be valid. | |
| - Department must be valid. | |
| - Slots can be taken (random simulation for demo). | |
| """ | |
| # Validate department | |
| if req.department not in DEPARTMENTS: | |
| result = BookingResponse(success=False, reason=f"Unknown department: {req.department}") | |
| _log_booking({"timestamp": datetime.now().isoformat(), **result.dict()}) | |
| return result | |
| # Validate slot | |
| if req.slot not in AVAILABLE_SLOTS: | |
| result = BookingResponse(success=False, reason=f"Invalid time slot: {req.slot}") | |
| _log_booking({"timestamp": datetime.now().isoformat(), **result.dict()}) | |
| return result | |
| # Check slot availability (80% success rate in simulation) | |
| key = f"{req.department}::{req.date}" | |
| taken_slots = _booked_slots.get(key, []) | |
| if req.slot in taken_slots or random.random() < 0.20: | |
| result = BookingResponse( | |
| success=False, | |
| reason="Slot unavailable. Please choose another time." | |
| ) | |
| _log_booking({ | |
| "timestamp": datetime.now().isoformat(), | |
| "patient": req.patient_name, | |
| **result.dict() | |
| }) | |
| return result | |
| # Confirm booking | |
| appointment_id = f"APT-{uuid.uuid4().hex[:6].upper()}" | |
| doctor = f"Dr. Sample_{random.randint(1, 5)}" | |
| # Persist to in-memory store | |
| _booked_slots.setdefault(key, []).append(req.slot) | |
| result = BookingResponse( | |
| success=True, | |
| appointment_id=appointment_id, | |
| patient_name=req.patient_name, | |
| department=req.department, | |
| date=req.date, | |
| slot=req.slot, | |
| doctor=doctor, | |
| ) | |
| _log_booking({ | |
| "timestamp": datetime.now().isoformat(), | |
| **result.dict() | |
| }) | |
| print(f"[BookingAPI] Confirmed: {appointment_id} for {req.patient_name}") | |
| return result | |
| def get_available_slots(department: str, date: str) -> dict: | |
| """Return remaining open slots for a department on a given date.""" | |
| key = f"{department}::{date}" | |
| taken = _booked_slots.get(key, []) | |
| open_slots = [s for s in AVAILABLE_SLOTS if s not in taken] | |
| return {"department": department, "date": date, "available_slots": open_slots} | |
| def health(): | |
| return {"status": "ok"} | |
| if __name__ == "__main__": | |
| import importlib | |
| try: | |
| uvicorn = importlib.import_module("uvicorn") | |
| except ImportError as exc: | |
| raise RuntimeError( | |
| "uvicorn is required to run the booking API directly. " | |
| "Install it with 'pip install uvicorn'." | |
| ) from exc | |
| uvicorn.run("src.booking_api:app", host="0.0.0.0", port=8000, reload=True) |