clinical-ner / app /server_clinical_ner.py
santanche's picture
feat (start): initial setup
6f1db1f
Raw
History Blame
3.14 kB
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from clinical_ner import ClinicalNER
import uvicorn
# Initialize FastAPI app
app = FastAPI(
title="Clinical NER API",
description="Named Entity Recognition API using Bio_ClinicalBERT",
version="1.0.0"
)
# Initialize the NER model (singleton pattern)
ner_model = None
@app.on_event("startup")
async def startup_event():
"""Load the NER model on startup"""
global ner_model
ner_model = ClinicalNER()
print("NER model loaded successfully!")
# Request model
class TextRequest(BaseModel):
text: str
class Config:
json_schema_extra = {
"example": {
"text": "Patient presents with hypertension and diabetes. Prescribed metformin 500mg."
}
}
# Response models
class Entity(BaseModel):
entity_group: str
score: float
word: str
start: int
end: int
class BasicNERResponse(BaseModel):
entities: list[Entity]
count: int
class PrologNERResponse(BaseModel):
prolog_facts: str
count: int
@app.get("/")
async def root():
"""Root endpoint with API information"""
return {
"message": "Clinical NER API",
"endpoints": {
"/ner/basic": "POST - Get basic NER annotations",
"/ner/prolog": "POST - Get Prolog facts",
"/docs": "GET - Interactive API documentation"
}
}
@app.post("/ner/basic", response_model=BasicNERResponse)
async def ner_basic(request: TextRequest):
"""
Perform basic NER on the input text.
Returns a list of detected entities with their types, positions, and confidence scores.
"""
try:
if not request.text.strip():
raise HTTPException(status_code=400, detail="Text cannot be empty")
entities = ner_model.basic_ner(request.text)
return {
"entities": entities,
"count": len(entities)
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error processing text: {str(e)}")
@app.post("/ner/prolog", response_model=PrologNERResponse)
async def ner_prolog(request: TextRequest):
"""
Perform NER and return results as Prolog facts.
Returns Prolog facts in the format: entity(Id, Type, Word, Start, End, Score).
"""
try:
if not request.text.strip():
raise HTTPException(status_code=400, detail="Text cannot be empty")
prolog_facts = ner_model.prolog_ner(request.text)
# Count the number of facts (lines)
count = len(prolog_facts.split('\n')) if prolog_facts else 0
return {
"prolog_facts": prolog_facts,
"count": count
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error processing text: {str(e)}")
@app.get("/health")
async def health_check():
"""Health check endpoint"""
return {
"status": "healthy",
"model_loaded": ner_model is not None
}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)