Ramosh99 commited on
Commit
55012e5
Β·
1 Parent(s): 7048093

fix: use demo.launch() for ZeroGPU compliance + attach REST routes to gr_app

Browse files
Files changed (2) hide show
  1. app.py +43 -50
  2. requirements.txt +0 -1
app.py CHANGED
@@ -1,16 +1,12 @@
 
1
  import os
2
- import uvicorn
3
  import gradio as gr
4
- import torch
5
  from transformers import pipeline
6
- from fastapi import FastAPI, HTTPException
7
  from fastapi.middleware.cors import CORSMiddleware
8
  from pydantic import BaseModel, ConfigDict
9
  from typing import List
10
 
11
- import spaces
12
-
13
-
14
  # ── Model ──────────────────────────────────────────────────────────────────────
15
  ner = pipeline(
16
  "ner",
@@ -20,7 +16,7 @@ ner = pipeline(
20
  )
21
 
22
 
23
- # ── Core logic (shared by Gradio UI + REST API) ────────────────────────────────
24
  @spaces.GPU
25
  def detect_pii(text: str):
26
  """Run NER and return structured PII results."""
@@ -47,10 +43,40 @@ def detect_pii(text: str):
47
  return {"text": text, "entities": highlighted}
48
 
49
 
50
- # ── FastAPI app ────────────────────────────────────────────────────────────────
51
- app = FastAPI(title="PII Detector API", version="1.0.0")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
- app.add_middleware(
 
 
 
 
 
 
 
 
 
 
54
  CORSMiddleware,
55
  allow_origins=["*"],
56
  allow_methods=["*"],
@@ -60,11 +86,7 @@ app.add_middleware(
60
 
61
  class DetectRequest(BaseModel):
62
  model_config = ConfigDict(
63
- json_schema_extra={
64
- "example": {
65
- "text": "Mage name Kamal, phone 071-1234567"
66
- }
67
- }
68
  )
69
  text: str
70
 
@@ -82,20 +104,18 @@ class DetectResponse(BaseModel):
82
  redacted_text: str
83
 
84
 
85
- @app.get("/api/health")
86
  def health_check():
87
  """Health check endpoint."""
88
  return {"status": "ok", "model": "Ramosh99/mixcode_pii_detector"}
89
 
90
 
91
- @app.post("/api/detect", response_model=DetectResponse)
92
  def api_detect_pii(request: DetectRequest):
93
  """
94
- Detect PII entities in the provided text.
95
-
96
- - **text**: Input Sinhala-English code-mixed text
97
 
98
- Returns detected entities with their positions, confidence scores,
99
  and a redacted version of the original text.
100
  """
101
  if not request.text.strip():
@@ -103,7 +123,6 @@ def api_detect_pii(request: DetectRequest):
103
 
104
  result = detect_pii(request.text)
105
 
106
- # Build redacted text by replacing entity spans with [ENTITY_TYPE]
107
  text = result["text"]
108
  entities = sorted(result["entities"], key=lambda e: e["start"], reverse=True)
109
  redacted = text
@@ -117,31 +136,5 @@ def api_detect_pii(request: DetectRequest):
117
  }
118
 
119
 
120
- # ── Gradio UI ──────────────────────────────────────────────────────────────────
121
- demo = gr.Interface(
122
- fn=detect_pii,
123
- inputs=gr.Textbox(
124
- label="Input Text",
125
- placeholder="Enter Sinhala-English codemixed text...",
126
- lines=4,
127
- ),
128
- outputs=gr.HighlightedText(label="Detected PII Entities"),
129
- title="Sinhala-English Codemix PII Detector",
130
- description=(
131
- "Detects PII entities (PERSON, ORG, PHONE, EMAIL, NIC, etc.) in "
132
- "Sinhala-English code-mixed text using the Ramosh99/mixcode_pii_detector model.\n\n"
133
- "**REST API:** POST `/api/detect` with `{\"text\": \"...\"}` Β· Docs: `/docs`"
134
- ),
135
- examples=[
136
- ["Mage name Kamal, man wada karanne MAS Holdings eke, phone 071-1234567"],
137
- ["ࢸ࢜ේ email address kamal.perera@gmail.com, NIC number 199912345678"],
138
- ["I live in Colombo and my phone number is 0771234567"],
139
- ],
140
- flagging_mode="never",
141
- )
142
-
143
- # Mount Gradio inside FastAPI so both the UI and the API are served together
144
- app = gr.mount_gradio_app(app, demo, path="/")
145
-
146
- # Start the ASGI server β€” keeps the process alive on HF Spaces
147
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
+ import spaces
2
  import os
 
3
  import gradio as gr
 
4
  from transformers import pipeline
5
+ from fastapi import HTTPException
6
  from fastapi.middleware.cors import CORSMiddleware
7
  from pydantic import BaseModel, ConfigDict
8
  from typing import List
9
 
 
 
 
10
  # ── Model ──────────────────────────────────────────────────────────────────────
11
  ner = pipeline(
12
  "ner",
 
16
  )
17
 
18
 
19
+ # ── Core inference (ZeroGPU) ───────────────────────────────────────────────────
20
  @spaces.GPU
21
  def detect_pii(text: str):
22
  """Run NER and return structured PII results."""
 
43
  return {"text": text, "entities": highlighted}
44
 
45
 
46
+ # ── Gradio UI ──────────────────────────────────────────────────────────────────
47
+ demo = gr.Interface(
48
+ fn=detect_pii,
49
+ inputs=gr.Textbox(
50
+ label="Input Text",
51
+ placeholder="Enter Sinhala-English codemixed text...",
52
+ lines=4,
53
+ ),
54
+ outputs=gr.HighlightedText(label="Detected PII Entities"),
55
+ title="Sinhala-English Codemix PII Detector",
56
+ description=(
57
+ "Detects PII entities (PERSON, ORG, PHONE, EMAIL, NIC, etc.) in "
58
+ "Sinhala-English code-mixed text using the Ramosh99/mixcode_pii_detector model.\n\n"
59
+ "**REST API:** POST `/api/detect` with `{\"text\": \"...\"}` Β· Docs: `/api/docs`"
60
+ ),
61
+ examples=[
62
+ ["Mage name Kamal, man wada karanne MAS Holdings eke, phone 071-1234567"],
63
+ ["ࢸ࢜ේ email address kamal.perera@gmail.com, NIC number 199912345678"],
64
+ ["I live in Colombo and my phone number is 0771234567"],
65
+ ],
66
+ flagging_mode="never",
67
+ )
68
 
69
+ # ── Launch Gradio (non-blocking) β€” properly initialises ZeroGPU ───────────────
70
+ # demo.launch() returns Gradio's internal FastAPI app which we extend below.
71
+ gr_app, _local_url, _share_url = demo.launch(
72
+ server_name="0.0.0.0",
73
+ server_port=7860,
74
+ prevent_thread_lock=True,
75
+ show_api=False,
76
+ )
77
+
78
+ # ── REST API routes added to Gradio's FastAPI app ─────────────────────────────
79
+ gr_app.add_middleware(
80
  CORSMiddleware,
81
  allow_origins=["*"],
82
  allow_methods=["*"],
 
86
 
87
  class DetectRequest(BaseModel):
88
  model_config = ConfigDict(
89
+ json_schema_extra={"example": {"text": "Mage name Kamal, phone 071-1234567"}}
 
 
 
 
90
  )
91
  text: str
92
 
 
104
  redacted_text: str
105
 
106
 
107
+ @gr_app.get("/api/health")
108
  def health_check():
109
  """Health check endpoint."""
110
  return {"status": "ok", "model": "Ramosh99/mixcode_pii_detector"}
111
 
112
 
113
+ @gr_app.post("/api/detect", response_model=DetectResponse)
114
  def api_detect_pii(request: DetectRequest):
115
  """
116
+ Detect PII entities in Sinhala-English code-mixed text.
 
 
117
 
118
+ Returns detected entities with positions, confidence scores,
119
  and a redacted version of the original text.
120
  """
121
  if not request.text.strip():
 
123
 
124
  result = detect_pii(request.text)
125
 
 
126
  text = result["text"]
127
  entities = sorted(result["entities"], key=lambda e: e["start"], reverse=True)
128
  redacted = text
 
136
  }
137
 
138
 
139
+ # ── Keep the process alive ─────────────────────────────────────────────────────
140
+ demo.block_thread()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -3,5 +3,4 @@ torch>=2.2.0
3
  sentencepiece>=0.2.0
4
  huggingface_hub>=0.19.3,<0.26.0
5
  fastapi>=0.110.0
6
- uvicorn>=0.29.0
7
  pydantic>=2.0.0
 
3
  sentencepiece>=0.2.0
4
  huggingface_hub>=0.19.3,<0.26.0
5
  fastapi>=0.110.0
 
6
  pydantic>=2.0.0