main.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import os
  2. import uuid
  3. from datetime import datetime
  4. from fastapi import FastAPI, UploadFile, File, Header, HTTPException, status, Form
  5. from fastapi.middleware.cors import CORSMiddleware
  6. from typing import Optional, List
  7. from backend.services.openai_service import extract_receipt_data
  8. from backend.schemas import ExtractionResponse, ClaimRecord, UserAccount, ClaimSubmission
  9. from dotenv import load_dotenv
  10. load_dotenv()
  11. app = FastAPI(title="AI-Assisted Data Entry API")
  12. # Configure CORS
  13. app.add_middleware(
  14. CORSMiddleware,
  15. allow_origins=["*"], # Adjust as needed for Angular frontend
  16. allow_credentials=True,
  17. allow_methods=["*"],
  18. allow_headers=["*"],
  19. )
  20. # In-memory database
  21. CLAIMS_DB: List[ClaimRecord] = []
  22. USERS_DB: List[UserAccount] = []
  23. @app.get("/health")
  24. async def health_check():
  25. return {"status": "healthy"}
  26. @app.get("/api/v1/users", response_model=List[UserAccount])
  27. async def get_users():
  28. return USERS_DB
  29. @app.post("/api/v1/users", response_model=UserAccount)
  30. async def create_user(user: UserAccount):
  31. USERS_DB.append(user)
  32. return user
  33. @app.post("/api/v1/extract", response_model=ExtractionResponse)
  34. async def extract_receipt(
  35. file: UploadFile = File(...),
  36. user_name: str = Form("Unknown Employee"),
  37. department: str = Form("Unknown Department")
  38. ):
  39. if not file.content_type.startswith("image/"):
  40. raise HTTPException(
  41. status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
  42. detail="File provided is not an image."
  43. )
  44. try:
  45. content = await file.read()
  46. extraction_result = await extract_receipt_data(content, user_name, department)
  47. if extraction_result is None:
  48. raise HTTPException(
  49. status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
  50. detail="Could not extract data from the provided image."
  51. )
  52. return extraction_result
  53. except Exception as e:
  54. raise HTTPException(
  55. status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
  56. detail=f"An error occurred during extraction: {str(e)}"
  57. )
  58. @app.post("/api/v1/claims", response_model=ClaimRecord)
  59. async def submit_claim(
  60. submission_data: ClaimSubmission,
  61. user_id: str = Header(...)
  62. ):
  63. # 1. Find User
  64. user = next((u for u in USERS_DB if u.id == user_id), None)
  65. if not user:
  66. raise HTTPException(status_code=404, detail="User not found")
  67. # 2. Financial Guard Logic
  68. spent_amount = submission_data.amount_spent
  69. remaining = user.medical_allowance
  70. amount_claimed = min(spent_amount, remaining)
  71. # 3. Update User Balance
  72. user.medical_allowance -= amount_claimed
  73. # 4. Save Claim
  74. claim = ClaimRecord(
  75. id=str(uuid.uuid4()),
  76. timestamp=datetime.now().isoformat(),
  77. submitted_by=user.name,
  78. department=user.department,
  79. amount_spent=spent_amount,
  80. amount_claimed=amount_claimed,
  81. provider_name=submission_data.provider_name,
  82. visit_date=submission_data.visit_date,
  83. extraction_data=submission_data.extraction_data
  84. )
  85. CLAIMS_DB.append(claim)
  86. return claim
  87. @app.get("/api/v1/claims", response_model=List[ClaimRecord])
  88. async def get_claims():
  89. return CLAIMS_DB
  90. if __name__ == "__main__":
  91. import uvicorn
  92. uvicorn.run(app, host="0.0.0.0", port=8000)