Sivaneshakumar's picture
Update app.py
bf70e53 verified
Raw
History Blame Contribute Delete
3.29 kB
try:
import spaces
has_spaces = True
except ImportError:
has_spaces = False
import asyncio
import gradio as gr
from fastapi.middleware.cors import CORSMiddleware
from backend.app.api.v1.router import api_router
from backend.app.ml.manager import model_manager
from backend.app.core.database import init_db
# 1. ZeroGPU worker function
def _run_ner(text: str):
if not text or not text.strip():
return "Please provide clinical text."
try:
service = model_manager.get_ner_service()
results = service.model.predict(text)
if not results:
return "No biomedical entities detected."
return "\n".join(
f"β€’ [{e.label}] {e.text} (Confidence: {round((e.confidence or 1.0)*100, 1)}%)"
for e in results
)
except Exception as e:
return f"Inference notice: {e}"
if has_spaces:
@spaces.GPU
def predict_ner(text: str):
return _run_ner(text)
else:
def predict_ner(text: str):
return _run_ner(text)
# 2. Gradio Interface β€” this IS the app ZeroGPU launches, so it must be the
# thing that actually calls .launch() below.
with gr.Blocks(title="SanjeevaniAI Healthcare Intelligence") as demo:
gr.Markdown("# πŸ₯ SanjeevaniAI β€” Healthcare Intelligence Engine")
gr.Markdown(
"Backend REST API Engine powered by **FastAPI** on Hugging Face **ZeroGPU**.\n\n"
"- **Health Status**: `/api/v1/health`\n"
"- **NER Analysis**: `/api/v1/ner/analyze`"
)
with gr.Row():
inp = gr.Textbox(
label="Test Clinical Text",
value="Metformin 500mg prescribed for type 2 diabetes mellitus and hypertension.",
)
out = gr.Textbox(label="ZeroGPU Extracted Biomedical Entities")
btn = gr.Button("⚑ Run ZeroGPU Clinical NER", variant="primary")
btn.click(fn=predict_ner, inputs=inp, outputs=out)
async def _startup():
await init_db()
try:
model_manager.initialize()
except Exception as e:
print(f"ML Model initialization: {e}")
def main():
# prevent_thread_lock=True makes launch() return instead of blocking,
# so we can attach to the REAL, live app object it just built.
# Anything attached to demo.app BEFORE this call gets discarded β€”
# launch() rebuilds the app internally to apply ssr_mode etc.
demo.launch(
server_name="0.0.0.0",
server_port=7860,
ssr_mode=False,
prevent_thread_lock=True,
)
# --- Everything below runs against the app that's actually serving traffic ---
demo.app.include_router(api_router, prefix="/api/v1")
# Defensive reset: guarantees add_middleware never raises
# "Cannot add middleware after an application has started",
# even if a request theoretically slipped in during the gap above.
demo.app.middleware_stack = None
demo.app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
asyncio.run(_startup())
# Keep the process alive β€” launch() no longer blocks on its own,
# so without this the script exits and the server dies immediately.
demo.block_thread()
if __name__ == "__main__":
main()