Distopia22 commited on
Commit
56edde7
·
0 Parent(s):

Initial backend deployment

Browse files
.gitattributes ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <<<<<<< HEAD
2
+ # Auto detect text files and perform LF normalization
3
+ * text=auto
4
+
5
+ # Python files
6
+ *.py text eol=lf
7
+ *.pyi text eol=lf
8
+
9
+ # Shell scripts
10
+ *.sh text eol=lf
11
+
12
+ # Docker files
13
+ Dockerfile text eol=lf
14
+ *.dockerfile text eol=lf
15
+
16
+ # Config files
17
+ *.yml text eol=lf
18
+ *.yaml text eol=lf
19
+ *.json text eol=lf
20
+ *.toml text eol=lf
21
+ *.ini text eol=lf
22
+ *.cfg text eol=lf
23
+
24
+ # Documentation
25
+ *.md text eol=lf
26
+ *.txt text eol=lf
27
+
28
+ # Git
29
+ .gitignore text eol=lf
30
+ .gitattributes text eol=lf
31
+
32
+ # Windows specific
33
+ *.bat text eol=crlf
34
+ *.cmd text eol=crlf
35
+ *.ps1 text eol=crlf
36
+ =======
37
+ *.7z filter=lfs diff=lfs merge=lfs -text
38
+ *.arrow filter=lfs diff=lfs merge=lfs -text
39
+ *.bin filter=lfs diff=lfs merge=lfs -text
40
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
41
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
42
+ *.ftz filter=lfs diff=lfs merge=lfs -text
43
+ *.gz filter=lfs diff=lfs merge=lfs -text
44
+ *.h5 filter=lfs diff=lfs merge=lfs -text
45
+ *.joblib filter=lfs diff=lfs merge=lfs -text
46
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
47
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
48
+ *.model filter=lfs diff=lfs merge=lfs -text
49
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
50
+ *.npy filter=lfs diff=lfs merge=lfs -text
51
+ *.npz filter=lfs diff=lfs merge=lfs -text
52
+ *.onnx filter=lfs diff=lfs merge=lfs -text
53
+ *.ot filter=lfs diff=lfs merge=lfs -text
54
+ *.parquet filter=lfs diff=lfs merge=lfs -text
55
+ *.pb filter=lfs diff=lfs merge=lfs -text
56
+ *.pickle filter=lfs diff=lfs merge=lfs -text
57
+ *.pkl filter=lfs diff=lfs merge=lfs -text
58
+ *.pt filter=lfs diff=lfs merge=lfs -text
59
+ *.pth filter=lfs diff=lfs merge=lfs -text
60
+ *.rar filter=lfs diff=lfs merge=lfs -text
61
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
62
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
63
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
64
+ *.tar filter=lfs diff=lfs merge=lfs -text
65
+ *.tflite filter=lfs diff=lfs merge=lfs -text
66
+ *.tgz filter=lfs diff=lfs merge=lfs -text
67
+ *.wasm filter=lfs diff=lfs merge=lfs -text
68
+ *.xz filter=lfs diff=lfs merge=lfs -text
69
+ *.zip filter=lfs diff=lfs merge=lfs -text
70
+ *.zst filter=lfs diff=lfs merge=lfs -text
71
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
72
+ >>>>>>> cc72a56032827788eed3105a0ef90e037552e5a7
.gitignore ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Environment variables
2
+ .env
3
+
4
+ # Python
5
+ __pycache__/
6
+ *.py[cod]
7
+ *$py.class
8
+ *.so
9
+ .Python
10
+ env/
11
+ venv/
12
+ ENV/
13
+ build/
14
+ dist/
15
+ *.egg-info/
16
+
17
+ # IDE
18
+ .vscode/
19
+ .idea/
20
+ *.swp
21
+ *.swo
22
+
23
+ # OS
24
+ .DS_Store
25
+ Thumbs.db
26
+
27
+ # Test
28
+ .pytest_cache/
29
+ .coverage
30
+ htmlcov/
Dockerfile ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # Copy requirements first for better caching
6
+ COPY requirements.txt .
7
+
8
+ # Install dependencies
9
+ RUN pip install --no-cache-dir -r requirements.txt
10
+
11
+ # Copy the entire backend
12
+ COPY . .
13
+
14
+ # Expose port 7860 (Hugging Face Spaces default)
15
+ EXPOSE 7860
16
+
17
+ # Run the application
18
+ CMD ["python", "src/main.py"]
how_to_run.txt ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <<<<<<< HEAD
2
+ # ICD-CPT Model
3
+
4
+ This project implements a FastAPI application that utilizes the Groq API and a language model (Llama 3.3 70b Versatile) to provide CPT and ICD coding based on provider notes. The application is designed to return structured JSON responses that include the predicted codes along with explanations for each code.
5
+
6
+ ## Project Structure
7
+
8
+ - **src/**: Contains the main application code.
9
+ - **main.py**: Entry point for the FastAPI application.
10
+ - **api/**: Contains API route definitions.
11
+ - **routes.py**: Defines the endpoints for the application.
12
+ - **services/**: Contains service logic for interacting with external APIs.
13
+ - **groq_service.py**: Handles requests to the Groq API and processes responses.
14
+ - **models/**: Contains data models for requests and responses.
15
+ - **request_models.py**: Defines request models for incoming data.
16
+ - **response_models.py**: Defines response models for outgoing data.
17
+ - **config/**: Contains configuration settings for the application.
18
+ - **settings.py**: Configuration for API keys and model IDs.
19
+ - **utils/**: Contains utility functions and prompt templates.
20
+ - **prompts.py**: Defines prompt templates for querying the model.
21
+
22
+ - **tests/**: Contains unit tests for the application.
23
+ - **test_api.py**: Tests for API endpoints.
24
+
25
+ - **requirements.txt**: Lists the dependencies required for the project.
26
+
27
+ - **.env.example**: Template for environment variables.
28
+
29
+ - **.gitignore**: Specifies files to be ignored by Git.
30
+
31
+ - **Dockerfile**: Instructions for building a Docker image for the application.
32
+
33
+ ## Setup Instructions
34
+
35
+ 1. **Clone the Repository**:
36
+ Clone the repository to your local machine.
37
+
38
+ 2. **Create a Virtual Environment**:
39
+ Create a virtual environment to manage dependencies.
40
+ ```
41
+ python -m venv venv
42
+ ```
43
+
44
+ 3. **Activate the Virtual Environment**:
45
+ Activate the virtual environment.
46
+ - On Windows:
47
+ ```
48
+ venv\Scripts\activate
49
+ ```
50
+ - On macOS/Linux:
51
+ ```
52
+ source venv/bin/activate
53
+ ```
54
+
55
+ 4. **Install Dependencies**:
56
+ Install the required dependencies using pip.
57
+ ```
58
+ pip install -r requirements.txt
59
+ ```
60
+
61
+ 5. **Set Up Environment Variables**:
62
+ Copy `.env.example` to `.env` and fill in the necessary values, including the Groq API key and model ID.
63
+
64
+ 6. **Run the Application**:
65
+ Start the FastAPI application.
66
+ ```
67
+ uvicorn src.main:app --reload
68
+ ```
69
+
70
+ ## Usage
71
+
72
+ - **Endpoint**: `/api/coding`
73
+ - **Method**: `POST`
74
+ - **Request Body**:
75
+ ```json
76
+ {
77
+ "provider_notes": "Your provider notes here."
78
+ }
79
+ ```
80
+
81
+ - **Response**:
82
+ ```json
83
+ {
84
+ "icd_codes": [
85
+ {
86
+ "code": "ICD_CODE_1",
87
+ "explanation": "Explanation for ICD_CODE_1"
88
+ }
89
+ ],
90
+ "cpt_codes": [
91
+ {
92
+ "code": "CPT_CODE_1",
93
+ "explanation": "Explanation for CPT_CODE_1"
94
+ }
95
+ ]
96
+ }
97
+ ```
98
+
99
+ ## Deployment
100
+
101
+ For deployment, you can use Docker to containerize the application. Follow the instructions in the Dockerfile to build and run the application in a containerized environment.
102
+
103
+ ## License
104
+
105
+ This project is licensed under the MIT License. See the LICENSE file for more details.
106
+ =======
107
+ ---
108
+ title: Icd Cpt Coding Api
109
+ emoji: 📈
110
+ colorFrom: indigo
111
+ colorTo: indigo
112
+ sdk: docker
113
+ pinned: false
114
+ ---
115
+
116
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
117
+ >>>>>>> cc72a56032827788eed3105a0ef90e037552e5a7
readme.md ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: ICD CPT Coding API Backend
3
+ emoji: 🔧
4
+ colorFrom: blue
5
+ colorTo: green
6
+ sdk: docker
7
+ pinned: false
8
+ license: mit
9
+ ---
10
+
11
+ # ICD-10 and CPT Coding API - Backend
12
+
13
+ FastAPI backend service for medical coding analysis.
14
+
15
+ ## API Endpoints
16
+
17
+ - **POST /api/v1/analyze** - Analyze provider notes
18
+ - **GET /api/v1/health** - Health check
19
+
20
+ ## Documentation
21
+
22
+ - Interactive Docs: `/docs`
23
+ - ReDoc: `/redoc`
24
+
25
+ ## Environment Variables
26
+
27
+ Set in Hugging Face Space Settings → Repository secrets:
28
+
29
+ - `GROQ_API_KEY`
30
+ - `MODEL_ID`
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ fastapi==0.104.1
2
+ uvicorn[standard]==0.24.0
3
+ groq==0.11.0
4
+ pydantic==2.5.0
5
+ python-dotenv==1.0.0
6
+ httpx==0.27.0
src/api/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # The contents of the file: /icd-cpt-model/icd-cpt-model/src/api/__init__.py
2
+
3
+ # This file is intentionally left blank.
src/api/routes.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, HTTPException
2
+ import sys
3
+ import os
4
+
5
+ # Add parent directory to path for imports
6
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
7
+
8
+ from models.request_models import ProviderNotesRequest
9
+ from models.response_models import CodingResponse
10
+ from services.groq_service import groq_service
11
+
12
+ router = APIRouter(prefix="/api/v1", tags=["Medical Coding"])
13
+
14
+ @router.post("/analyze", response_model=CodingResponse)
15
+ async def analyze_provider_notes(request: ProviderNotesRequest):
16
+ """
17
+ Analyze provider notes and return ICD-10 and CPT codes with explanations.
18
+
19
+ - **provider_notes**: The medical provider notes to analyze
20
+
21
+ Returns ICD-10 codes, CPT codes, and explanations for each.
22
+ """
23
+ try:
24
+ result = await groq_service.analyze_provider_notes(request.provider_notes)
25
+ return CodingResponse(**result)
26
+ except ValueError as e:
27
+ raise HTTPException(status_code=422, detail=str(e))
28
+ except Exception as e:
29
+ raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
30
+
31
+ @router.get("/health")
32
+ async def health_check():
33
+ """Health check endpoint"""
34
+ return {"status": "healthy", "service": "ICD-CPT Coding API"}
src/config/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # The contents of the file: /icd-cpt-model/icd-cpt-model/src/config/__init__.py
2
+
3
+ # This file is intentionally left blank.
src/config/settings.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+
4
+ # Load environment variables from .env file
5
+ load_dotenv()
6
+
7
+ class Settings:
8
+ def __init__(self):
9
+ self.GROQ_API_KEY = os.getenv("GROQ_API_KEY")
10
+ self.MODEL_ID = os.getenv("MODEL_ID", "llama-3.3-70b-versatile")
11
+
12
+ # Validate required environment variables
13
+ if not self.GROQ_API_KEY:
14
+ raise ValueError(
15
+ "GROQ_API_KEY not found in environment variables. "
16
+ "Please set it in Hugging Face Space Settings -> Repository secrets"
17
+ )
18
+
19
+ print(f"✅ Settings loaded successfully")
20
+ print(f"✅ Model ID: {self.MODEL_ID}")
21
+ print(f"✅ API Key configured: {self.GROQ_API_KEY[:10]}...")
22
+
23
+ settings = Settings()
src/main.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ import sys
4
+ import os
5
+
6
+ # Add current directory to path
7
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
8
+
9
+ from api.routes import router
10
+
11
+ app = FastAPI(
12
+ title="ICD-10 and CPT Coding API",
13
+ description="Analyzes medical provider notes and returns appropriate ICD-10 and CPT codes with explanations",
14
+ version="1.0.0",
15
+ docs_url="/docs",
16
+ redoc_url="/redoc"
17
+ )
18
+
19
+ # CORS middleware
20
+ app.add_middleware(
21
+ CORSMiddleware,
22
+ allow_origins=["*"],
23
+ allow_credentials=True,
24
+ allow_methods=["*"],
25
+ allow_headers=["*"],
26
+ )
27
+
28
+ # Include routers
29
+ app.include_router(router)
30
+
31
+ @app.get("/")
32
+ async def root():
33
+ return {
34
+ "message": "ICD-10 and CPT Coding API",
35
+ "docs": "/docs",
36
+ "health": "/api/v1/health"
37
+ }
38
+
39
+ if __name__ == "__main__":
40
+ import uvicorn
41
+ uvicorn.run(app, host="0.0.0.0", port=7860)
src/models/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # The contents of the file: /icd-cpt-model/icd-cpt-model/src/models/__init__.py
2
+
3
+ # This file is intentionally left blank.
src/models/request_models.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel, Field
2
+
3
+ class ProviderNotesRequest(BaseModel):
4
+ provider_notes: str = Field(
5
+ ...,
6
+ description="The medical provider notes to analyze",
7
+ min_length=10,
8
+ example="Patient presents with acute bronchitis. Performed comprehensive examination and prescribed antibiotics."
9
+ )
10
+
11
+ class Config:
12
+ json_schema_extra = {
13
+ "example": {
14
+ "provider_notes": "Patient presents with acute bronchitis. Cough for 5 days, productive with yellow sputum. Lung exam reveals diffuse wheezing. Prescribed azithromycin 500mg."
15
+ }
16
+ }
17
+
18
+ class ProviderNote(BaseModel):
19
+ note: str
20
+
21
+ class CodingResponse(BaseModel):
22
+ cpt_codes: list
23
+ cpt_explanation: str
24
+ icd_codes: list
25
+ icd_explanation: str
src/models/response_models.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel, Field
2
+ from typing import List
3
+
4
+ class ICDCode(BaseModel):
5
+ code: str = Field(..., description="ICD-10 diagnosis code")
6
+ description: str = Field(..., description="Description of the diagnosis")
7
+ explanation: str = Field(..., description="Explanation for why this code was selected")
8
+
9
+ class CPTCode(BaseModel):
10
+ code: str = Field(..., description="CPT procedure code")
11
+ description: str = Field(..., description="Description of the procedure/service")
12
+ explanation: str = Field(..., description="Explanation for why this code was selected")
13
+
14
+ class CodingResponse(BaseModel):
15
+ icd_codes: List[ICDCode] = Field(default_factory=list, description="List of ICD-10 codes")
16
+ cpt_codes: List[CPTCode] = Field(default_factory=list, description="List of CPT codes")
17
+ overall_summary: str = Field(..., description="Overall summary of coding decisions")
18
+
19
+ class Config:
20
+ json_schema_extra = {
21
+ "example": {
22
+ "icd_codes": [
23
+ {
24
+ "code": "J20.9",
25
+ "description": "Acute bronchitis, unspecified",
26
+ "explanation": "Patient presents with acute bronchitis as documented in provider notes"
27
+ }
28
+ ],
29
+ "cpt_codes": [
30
+ {
31
+ "code": "99213",
32
+ "description": "Office visit, established patient",
33
+ "explanation": "Comprehensive examination performed as documented"
34
+ }
35
+ ],
36
+ "overall_summary": "Patient encounter for acute bronchitis with examination and treatment"
37
+ }
38
+ }
src/services/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # The contents of the file: /icd-cpt-model/icd-cpt-model/src/services/__init__.py
2
+
3
+ # This file is intentionally left blank.
src/services/groq_service.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from groq import Groq
2
+ import json
3
+ import sys
4
+ import os
5
+
6
+ # Add parent directory to path for imports
7
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8
+
9
+ from config.settings import settings
10
+ from utils.prompts import SYSTEM_PROMPT, create_user_prompt
11
+
12
+ class GroqService:
13
+ def __init__(self):
14
+ try:
15
+ print(f"🔧 Initializing Groq client...")
16
+ self.client = Groq(api_key=settings.GROQ_API_KEY)
17
+ self.model_id = settings.MODEL_ID
18
+ print(f"✅ Groq client initialized successfully with model: {self.model_id}")
19
+ except Exception as e:
20
+ print(f"❌ Failed to initialize Groq client: {str(e)}")
21
+ raise
22
+
23
+ async def analyze_provider_notes(self, provider_notes: str) -> dict:
24
+ """
25
+ Analyze provider notes and return ICD and CPT codes with explanations
26
+ """
27
+ try:
28
+ print(f"📝 Analyzing provider notes...")
29
+ # Create the chat completion with system and user prompts
30
+ chat_completion = self.client.chat.completions.create(
31
+ messages=[
32
+ {
33
+ "role": "system",
34
+ "content": SYSTEM_PROMPT
35
+ },
36
+ {
37
+ "role": "user",
38
+ "content": create_user_prompt(provider_notes)
39
+ }
40
+ ],
41
+ model=self.model_id,
42
+ temperature=0.1, # Low temperature for consistent, factual outputs
43
+ response_format={"type": "json_object"} # Force JSON response
44
+ )
45
+
46
+ # Extract and parse the response
47
+ response_content = chat_completion.choices[0].message.content
48
+ print(f"✅ Received response from Groq API")
49
+ parsed_response = json.loads(response_content)
50
+
51
+ return parsed_response
52
+
53
+ except json.JSONDecodeError as e:
54
+ print(f"❌ JSON parsing error: {str(e)}")
55
+ raise ValueError(f"Failed to parse JSON response from model: {str(e)}")
56
+ except Exception as e:
57
+ print(f"❌ Groq API error: {str(e)}")
58
+ raise Exception(f"Error calling Groq API: {str(e)}")
59
+
60
+ # Don't initialize here - let it be initialized when imported
61
+ groq_service = GroqService()
src/utils/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ # This file is intentionally left blank.
src/utils/prompts.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ SYSTEM_PROMPT = """You are a specialized medical coding assistant AI that analyzes clinical provider notes and assigns appropriate ICD-10 and CPT codes.
2
+
3
+ CRITICAL INSTRUCTIONS:
4
+ 1. You MUST respond ONLY in valid JSON format as specified below
5
+ 2. Do NOT hallucinate or make up codes - only use codes you are confident about
6
+ 3. If you are uncertain about any code, do NOT include it in the response
7
+ 4. If you cannot find any relevant ICD or CPT codes, return empty arrays for those sections
8
+ 5. Always provide clear, evidence-based explanations for each code you assign
9
+ 6. Your response must be parseable JSON - do not add any text before or after the JSON object
10
+
11
+ REQUIRED JSON FORMAT:
12
+ {
13
+ "icd_codes": [
14
+ {
15
+ "code": "ICD-10 code",
16
+ "description": "Description of the diagnosis",
17
+ "explanation": "Detailed explanation of why this code was selected based on the provider notes"
18
+ }
19
+ ],
20
+ "cpt_codes": [
21
+ {
22
+ "code": "CPT code",
23
+ "description": "Description of the procedure/service",
24
+ "explanation": "Detailed explanation of why this code was selected based on the provider notes"
25
+ }
26
+ ],
27
+ "overall_summary": "Brief summary of the coding decisions"
28
+ }
29
+
30
+ CODING PRINCIPLES:
31
+ - Only assign codes that are clearly supported by documentation in the provider notes
32
+ - Be conservative - if unsure, omit the code rather than guess
33
+ - Prioritize accuracy over quantity
34
+ - Each explanation must reference specific details from the provider notes
35
+ - If no relevant codes can be determined, respond with empty arrays
36
+
37
+ Remember: Return ONLY the JSON object, nothing else."""
38
+
39
+ def create_user_prompt(provider_notes: str) -> str:
40
+ """Create the user prompt with provider notes"""
41
+ return f"""Analyze the following provider notes and extract appropriate ICD-10 and CPT codes.
42
+
43
+ PROVIDER NOTES:
44
+ {provider_notes}
45
+
46
+ Respond ONLY with the JSON object following the exact format specified in the system prompt."""
tests/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ # This file is intentionally left blank.
tests/test_api.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi.testclient import TestClient
2
+ from src.main import app
3
+
4
+ client = TestClient(app)
5
+
6
+ def test_coding_endpoint():
7
+ provider_notes = {
8
+ "notes": "Patient has a fever and cough."
9
+ }
10
+
11
+ response = client.post("/api/coding", json=provider_notes)
12
+
13
+ assert response.status_code == 200
14
+ data = response.json()
15
+
16
+ assert "CPT" in data
17
+ assert "ICD" in data
18
+ assert isinstance(data["CPT"], list)
19
+ assert isinstance(data["ICD"], list)
20
+ assert "explanation" in data["CPT"][0]
21
+ assert "explanation" in data["ICD"][0]