finalyear226 commited on
Commit
e98a2be
·
verified ·
1 Parent(s): ea9b214

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. Dockerfile +6 -10
  2. README.md +40 -11
  3. app.py +82 -3
  4. requirements.txt +3 -2
Dockerfile CHANGED
@@ -1,16 +1,12 @@
1
- # Read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
2
- # you will also find guides on how best to write your Dockerfile
3
 
4
- FROM python:3.9
5
 
6
- RUN useradd -m -u 1000 user
7
- USER user
8
- ENV PATH="/home/user/.local/bin:$PATH"
9
 
10
- WORKDIR /app
11
 
12
- COPY --chown=user ./requirements.txt requirements.txt
13
- RUN pip install --no-cache-dir --upgrade -r requirements.txt
14
 
15
- COPY --chown=user . /app
16
  CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
 
1
+ FROM python:3.11-slim
 
2
 
3
+ WORKDIR /app
4
 
5
+ COPY requirements.txt .
6
+ RUN pip install --no-cache-dir -r requirements.txt
 
7
 
8
+ COPY app.py .
9
 
10
+ EXPOSE 7860
 
11
 
 
12
  CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,11 +1,40 @@
1
- ---
2
- title: Urtox Api
3
- emoji: 🐢
4
- colorFrom: pink
5
- colorTo: purple
6
- sdk: docker
7
- pinned: false
8
- license: mit
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # URTOX Hugging Face Space API
2
+
3
+ This folder is a small FastAPI backend scaffold for the open-house deployment.
4
+
5
+ ## Local run
6
+
7
+ ```bash
8
+ pip install -r requirements.txt
9
+ uvicorn app:app --host 0.0.0.0 --port 7860
10
+ ```
11
+
12
+ Then set the React app environment variable:
13
+
14
+ ```bash
15
+ REACT_APP_API_URL=http://localhost:7860
16
+ ```
17
+
18
+ ## Hugging Face Spaces
19
+
20
+ Create a new Space with:
21
+
22
+ - SDK: Docker
23
+ - Root files from this folder: `Dockerfile`, `app.py`, `requirements.txt`
24
+ - Port: `7860`
25
+
26
+ This scaffold currently returns demo predictions. Replace `demo_prediction()` in `app.py` with the real model inference from your notebooks.
27
+
28
+ ## Test endpoint
29
+
30
+ After the Space starts, call:
31
+
32
+ ```bash
33
+ POST https://your-space-name.hf.space/detect
34
+ Content-Type: application/json
35
+
36
+ {
37
+ "mode": "text",
38
+ "text": "yeh bad aur toxic jumla hai"
39
+ }
40
+ ```
app.py CHANGED
@@ -1,7 +1,86 @@
 
 
1
  from fastapi import FastAPI
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
- app = FastAPI()
4
 
5
  @app.get("/")
6
- def greet_json():
7
- return {"Hello": "World!"}
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
  from fastapi import FastAPI
4
+ from fastapi.middleware.cors import CORSMiddleware
5
+ from pydantic import BaseModel
6
+
7
+
8
+ app = FastAPI(title="URTOX Toxic Span Detection API")
9
+
10
+ app.add_middleware(
11
+ CORSMiddleware,
12
+ allow_origins=["*"],
13
+ allow_credentials=True,
14
+ allow_methods=["*"],
15
+ allow_headers=["*"],
16
+ )
17
+
18
+
19
+ class DetectRequest(BaseModel):
20
+ mode: str
21
+ text: Optional[str] = None
22
+ audio: Optional[str] = None
23
+
24
+
25
+ def demo_prediction(text: str, mode: str):
26
+ tokens = [token for token in text.split() if token]
27
+ if not tokens:
28
+ tokens = ["demo", "toxic", "span", "result"]
29
+
30
+ toxic_hints = {"bad", "hate", "idiot", "stupid", "gali", "toxic"}
31
+ toxic_indexes = [
32
+ index
33
+ for index, token in enumerate(tokens)
34
+ if any(hint in token.lower() for hint in toxic_hints)
35
+ ]
36
+ if not toxic_indexes:
37
+ toxic_indexes = [1 if len(tokens) > 1 else 0]
38
+
39
+ words = []
40
+ for index, token in enumerate(tokens):
41
+ is_toxic = index in toxic_indexes
42
+ words.append(
43
+ {
44
+ "text": token,
45
+ "toxic": is_toxic,
46
+ "bioTag": "B-Toxic" if is_toxic and index == toxic_indexes[0] else ("I-Toxic" if is_toxic else "O"),
47
+ "confidence": 0.89 if is_toxic else 0.08,
48
+ }
49
+ )
50
+
51
+ return {
52
+ "isToxic": True,
53
+ "confidence": 0.91,
54
+ "subLabel": "offensive",
55
+ "subLabelConfidence": 0.87,
56
+ "toxicSpanCount": len(toxic_indexes),
57
+ "transcript": text if mode == "audio" else None,
58
+ "words": words,
59
+ "xai": {
60
+ "modelExplanation": "Demo API response. Replace demo_prediction with the real XLM-R/Wav2Vec2 inference pipeline.",
61
+ "topToxicTokens": [
62
+ {
63
+ "token": tokens[index],
64
+ "attribution": 0.74,
65
+ "confidence": 0.89,
66
+ }
67
+ for index in toxic_indexes
68
+ ],
69
+ "integratedGradients": 0.78,
70
+ },
71
+ }
72
 
 
73
 
74
  @app.get("/")
75
+ def health():
76
+ return {"status": "ok", "service": "urtox-api"}
77
+
78
+
79
+ @app.post("/detect")
80
+ def detect(payload: DetectRequest):
81
+ if payload.mode == "audio":
82
+ text = "Demo transcript from uploaded or recorded Urdu audio"
83
+ else:
84
+ text = payload.text or "yeh demo toxic span detection result hai"
85
+
86
+ return demo_prediction(text, payload.mode)
requirements.txt CHANGED
@@ -1,2 +1,3 @@
1
- fastapi
2
- uvicorn[standard]
 
 
1
+ fastapi==0.115.6
2
+ uvicorn[standard]==0.34.0
3
+ python-multipart==0.0.20