samuelolubukun commited on
Commit
9e2e91e
·
verified ·
1 Parent(s): aeb0a12

Upload 4 files

Browse files
Files changed (4) hide show
  1. Dockerfile +34 -0
  2. README.md +16 -5
  3. app.py +152 -0
  4. requirements.txt +5 -0
Dockerfile ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use official lightweight Python image
2
+ FROM python:3.10-slim
3
+
4
+ # Create a secure, non-root user (required by Hugging Face Spaces)
5
+ RUN useradd -m -u 1000 user
6
+
7
+ # Set up environment variables
8
+ ENV HOME=/home/user \
9
+ PATH=/home/user/.local/bin:$PATH \
10
+ PYTHONUNBUFFERED=1 \
11
+ HF_HOME=/home/user/.cache/huggingface
12
+
13
+ # Set working directory
14
+ WORKDIR $HOME/app
15
+
16
+ # Copy requirements and install dependencies
17
+ COPY --chown=user requirements.txt .
18
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
19
+
20
+ # Pre-cache the model during the image build process
21
+ # This guarantees instant startup times when the Space boots up.
22
+ RUN python -c "from transformers import pipeline; pipeline('token-classification', model='samuelolubukun/pii-ner-edge-optimized')"
23
+
24
+ # Copy the rest of the application files
25
+ COPY --chown=user . .
26
+
27
+ # Switch to the non-root user
28
+ USER user
29
+
30
+ # Expose port 7860
31
+ EXPOSE 7860
32
+
33
+ # Start the application on port 7860
34
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,10 +1,21 @@
1
  ---
2
- title: PII Warden API
3
- emoji: 🐨
4
- colorFrom: pink
5
- colorTo: blue
6
  sdk: docker
 
7
  pinned: false
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: PII Warden AI
3
+ emoji: 🛡️
4
+ colorFrom: indigo
5
+ colorTo: pink
6
  sdk: docker
7
+ app_port: 7860
8
  pinned: false
9
  ---
10
 
11
+ # PII Warden Cloud AI Space
12
+
13
+ This is the Tier 2 Cloud AI Inference service for the PII Warden browser extension. It loads the fine-tuned `samuelolubukun/pii-ner-edge-optimized` DistilBERT NER model to detect unstructured PII entities (Names, Organizations, Locations).
14
+
15
+ ## How to use this Space with the Extension
16
+
17
+ 1. Copy the URL of this Hugging Face Space.
18
+ - Example: `https://<your-username>-pii-warden-ai.hf.space/analyze` (Note the `/analyze` path at the end!).
19
+ 2. Open the PII Warden browser extension popup.
20
+ 3. Paste the URL into the **"Cloud AI Endpoint"** field.
21
+ 4. The extension will automatically verify and connect, merging Cloud AI context detections with its local regex & checksum validator!
app.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from fastapi.responses import HTMLResponse
4
+ from pydantic import BaseModel
5
+ from transformers import pipeline
6
+ import uvicorn
7
+
8
+ app = FastAPI(
9
+ title="PII Warden Cloud AI Endpoint",
10
+ description="Tier 2 Cloud AI Inference service for the PII Warden browser extension."
11
+ )
12
+
13
+ # Enable CORS (Cross-Origin Resource Sharing)
14
+ # Critical so that browser extensions can send POST requests from any webpage.
15
+ app.add_middleware(
16
+ CORSMiddleware,
17
+ allow_origins=["*"],
18
+ allow_credentials=True,
19
+ allow_methods=["*"],
20
+ allow_headers=["*"],
21
+ )
22
+
23
+ class AnalyzeRequest(BaseModel):
24
+ text: str
25
+
26
+ # Load the Hugging Face Token Classification pipeline on startup
27
+ print("Loading DistilBERT PII model into memory...")
28
+ try:
29
+ nlp_pipeline = pipeline(
30
+ "token-classification",
31
+ model="samuelolubukun/pii-ner-edge-optimized",
32
+ aggregation_strategy="simple"
33
+ )
34
+ print("Model loaded successfully!")
35
+ except Exception as e:
36
+ print(f"Error loading model: {e}")
37
+ nlp_pipeline = None
38
+
39
+ @app.get("/", response_class=HTMLResponse)
40
+ async def read_root():
41
+ return """
42
+ <!DOCTYPE html>
43
+ <html>
44
+ <head>
45
+ <title>PII Warden AI Endpoint</title>
46
+ <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;600;700&display=swap" rel="stylesheet">
47
+ <style>
48
+ body {
49
+ font-family: 'Outfit', sans-serif;
50
+ background-color: #0b0f19;
51
+ color: #f3f4f6;
52
+ display: flex;
53
+ flex-direction: column;
54
+ justify-content: center;
55
+ align-items: center;
56
+ min-height: 100vh;
57
+ margin: 0;
58
+ background: radial-gradient(circle at top right, rgba(139, 92, 246, 0.15), transparent 60%),
59
+ radial-gradient(circle at bottom left, rgba(236, 72, 153, 0.1), transparent 60%);
60
+ }
61
+ .card {
62
+ background: rgba(17, 24, 39, 0.75);
63
+ border: 1px solid rgba(255, 255, 255, 0.08);
64
+ border-radius: 16px;
65
+ padding: 32px;
66
+ max-width: 500px;
67
+ text-align: center;
68
+ backdrop-filter: blur(12px);
69
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
70
+ }
71
+ h1 {
72
+ font-size: 2rem;
73
+ margin-bottom: 8px;
74
+ background: linear-gradient(135deg, #ffffff 30%, #a78bfa 100%);
75
+ -webkit-background-clip: text;
76
+ -webkit-text-fill-color: transparent;
77
+ }
78
+ p {
79
+ color: #9ca3af;
80
+ font-size: 0.95rem;
81
+ line-height: 1.5;
82
+ }
83
+ .badge {
84
+ display: inline-block;
85
+ background: rgba(16, 185, 129, 0.15);
86
+ color: #10b981;
87
+ border: 1px solid rgba(16, 185, 129, 0.3);
88
+ padding: 6px 16px;
89
+ border-radius: 9999px;
90
+ font-size: 0.8rem;
91
+ font-weight: 600;
92
+ text-transform: uppercase;
93
+ letter-spacing: 0.05em;
94
+ margin-top: 16px;
95
+ }
96
+ .endpoint {
97
+ background: rgba(10, 10, 10, 0.4);
98
+ padding: 10px;
99
+ border-radius: 8px;
100
+ font-family: monospace;
101
+ font-size: 0.85rem;
102
+ color: #f472b6;
103
+ margin-top: 20px;
104
+ border: 1px solid rgba(255, 255, 255, 0.05);
105
+ }
106
+ </style>
107
+ </head>
108
+ <body>
109
+ <div class="card">
110
+ <h1>🛡️ PII Warden AI</h1>
111
+ <p>Your hosted client-side PII redactor cloud inference endpoint is live. Configure your browser extension to query the endpoint below for Tier 2 context analysis.</p>
112
+ <div class="endpoint">POST /analyze</div>
113
+ <div class="badge">Online & Active</div>
114
+ </div>
115
+ </body>
116
+ </html>
117
+ """
118
+
119
+ @app.post("/analyze")
120
+ async def analyze_text(request: AnalyzeRequest):
121
+ if nlp_pipeline is None:
122
+ raise HTTPException(status_code=503, detail="AI Model pipeline not initialized.")
123
+
124
+ try:
125
+ text = request.text
126
+ if not text.strip():
127
+ return []
128
+
129
+ predictions = nlp_pipeline(text)
130
+
131
+ formatted_results = []
132
+ for pred in predictions:
133
+ formatted_results.append({
134
+ "entity_group": pred["entity_group"],
135
+ "score": float(pred["score"]),
136
+ "word": pred["word"],
137
+ "start": int(pred["start"]),
138
+ "end": int(pred["end"])
139
+ })
140
+
141
+ return formatted_results
142
+
143
+ except Exception as e:
144
+ raise HTTPException(status_code=500, detail=f"Inference error: {str(e)}")
145
+
146
+ @app.get("/health")
147
+ async def health_check():
148
+ return {"status": "healthy", "model_loaded": nlp_pipeline is not None}
149
+
150
+ if __name__ == "__main__":
151
+ # Hugging Face Spaces require listening on port 7860
152
+ uvicorn.run("app:app", host="0.0.0.0", port=7860, reload=False)
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ pydantic
4
+ transformers
5
+ torch