Distopia22's picture
Fix: Add remove_pii method to FileService
764e30e
raw
history blame
4.15 kB
import logging
from fastapi import APIRouter, HTTPException, UploadFile, File
from models.request_models import ProviderNotesRequest
from models.response_models import CodingResponse, FileUploadResponse
from services.groq_service import groq_service
from services.file_service import file_service
router = APIRouter()
logger = logging.getLogger(__name__)
@router.post("/coding", response_model=CodingResponse)
async def analyze_provider_notes(request: ProviderNotesRequest):
"""
Analyze provider notes and extract ICD-10 and CPT codes
This endpoint accepts provider notes as text input and returns:
- ICD-10 diagnostic codes with explanations
- CPT procedure codes with explanations
- Overall encounter summary
"""
try:
logger.info(f"📥 Received coding request (notes length: {len(request.provider_notes)})")
# Validate input
if not request.provider_notes or len(request.provider_notes.strip()) < 10:
raise HTTPException(
status_code=400,
detail="Provider notes must be at least 10 characters long"
)
# Analyze with Groq
result = groq_service.analyze_provider_notes(request.provider_notes)
logger.info(f"✅ Analysis complete: {len(result.get('icd_codes', []))} ICD codes, {len(result.get('cpt_codes', []))} CPT codes")
return result
except HTTPException:
raise
except ValueError as e:
logger.error(f"❌ Validation error: {str(e)}")
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
logger.error(f"❌ Error processing request: {str(e)}", exc_info=True)
raise HTTPException(status_code=500, detail=f"Error processing request: {str(e)}")
@router.post("/upload-file", response_model=FileUploadResponse)
async def upload_provider_notes_file(file: UploadFile = File(...)):
"""
Upload a provider notes file (.txt), remove PII, and analyze
Returns:
- File processing info (PII removal stats)
- ICD-10 codes with explanations
- CPT codes with explanations
- Overall summary
"""
try:
logger.info(f"📤 Received file upload: {file.filename}")
# Validate file type
if not file.filename.endswith('.txt'):
raise HTTPException(
status_code=400,
detail="Only .txt files are allowed"
)
# Read file content
content = await file.read()
text = content.decode('utf-8')
logger.info(f"📄 File read successfully (length: {len(text)})")
# Remove PII
try:
cleaned_text, pii_count = file_service.remove_pii(text)
logger.info(f"🔒 PII removal complete: {pii_count} entities removed")
except Exception as pii_error:
logger.error(f"⚠️ PII removal failed: {str(pii_error)}")
# Continue without PII removal if it fails
cleaned_text = text
pii_count = 0
# Analyze with Groq
result = groq_service.analyze_provider_notes(cleaned_text)
# Combine results
response = {
"success": True,
"filename": file.filename,
"extracted_text_length": len(text),
"pii_removed": pii_count > 0,
"pii_count": pii_count,
"icd_codes": result.get("icd_codes", []),
"cpt_codes": result.get("cpt_codes", []),
"overall_summary": result.get("overall_summary", "")
}
logger.info(f"✅ File processing complete")
return response
except HTTPException:
raise
except UnicodeDecodeError:
logger.error("❌ File encoding error")
raise HTTPException(status_code=400, detail="File must be UTF-8 encoded text")
except Exception as e:
logger.error(f"❌ Error processing uploaded file: {str(e)}", exc_info=True)
raise HTTPException(status_code=500, detail=f"Error processing uploaded file: {str(e)}")