n1th1sh commited on
Commit
0454eae
Β·
verified Β·
1 Parent(s): 24ddab8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -17
app.py CHANGED
@@ -7,20 +7,36 @@ from key_store import (
7
  )
8
 
9
  # ── Load your private HF model ────────────────────────────────────────────────
10
- HF_TOKEN = os.environ.get("HF_TOKEN") # set as a Space secret
11
  MODEL_ID = "Wardline/CLOAK_V2.2.7"
12
 
13
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, token=HF_TOKEN)
14
  model = AutoModelForTokenClassification.from_pretrained(MODEL_ID, token=HF_TOKEN)
15
  ner_pipe = pipeline("ner", model=model, tokenizer=tokenizer, aggregation_strategy="simple")
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  # ── PII detection ─────────────────────────────────────────────────────────────
18
  def detect_pii(text: str, api_key: str) -> dict:
19
  entry = validate_key(api_key)
20
  if not entry:
21
  return {"error": "Invalid or revoked API key.", "entities": []}
22
  increment_usage(api_key)
23
- entities = ner_pipe(text)
 
 
 
24
  return {
25
  "text": text,
26
  "entities": [
@@ -29,10 +45,10 @@ def detect_pii(text: str, api_key: str) -> dict:
29
  "word": e["word"],
30
  "score": round(e["score"], 4),
31
  "start": e["start"],
32
- "end": e["end"]
33
  }
34
  for e in entities
35
- ]
36
  }
37
 
38
  # ── Key management helpers ────────────────────────────────────────────────────
@@ -50,11 +66,11 @@ def get_key_table():
50
 
51
  def do_revoke(full_key):
52
  revoke_key(full_key.strip())
53
- return f"Key revoked.", get_key_table()
54
 
55
  def do_delete(full_key):
56
  delete_key(full_key.strip())
57
- return f"Key deleted.", get_key_table()
58
 
59
  # ── Gradio UI ─────────────────────────────────────────────────────────────────
60
  with gr.Blocks(title="PII Detection API") as demo:
@@ -65,18 +81,14 @@ with gr.Blocks(title="PII Detection API") as demo:
65
  api_key_in = gr.Textbox(label="API key", placeholder="pii_sk_...")
66
  text_in = gr.Textbox(label="Input text", lines=4,
67
  placeholder="Enter text to scan for PII...")
68
- detect_btn = gr.Button("Detect PII", variant="primary")
69
  output_json = gr.JSON(label="Results")
70
- detect_btn.click(
71
- fn=detect_pii,
72
- inputs=[text_in, api_key_in],
73
- outputs=output_json
74
- )
75
 
76
  with gr.Tab("API Key Management"):
77
  gr.Markdown("### Create a new key")
78
  with gr.Row():
79
- label_in = gr.Textbox(label="Key label", placeholder="e.g. production")
80
  create_btn = gr.Button("Generate key")
81
  create_msg = gr.Textbox(label="New key (copy now!)", interactive=False, lines=2)
82
 
@@ -84,7 +96,7 @@ with gr.Blocks(title="PII Detection API") as demo:
84
  key_df = gr.DataFrame(
85
  value=get_key_table(),
86
  headers=["Label", "Key preview", "Status", "Usage", "Created"],
87
- interactive=False
88
  )
89
 
90
  gr.Markdown("### Revoke or delete a key")
@@ -94,8 +106,8 @@ with gr.Blocks(title="PII Detection API") as demo:
94
  delete_btn = gr.Button("Delete", variant="stop")
95
  manage_msg = gr.Textbox(label="Result", interactive=False)
96
 
97
- create_btn.click(create_key, inputs=label_in, outputs=[create_msg, key_df])
98
- revoke_btn.click(do_revoke, inputs=manage_key_in, outputs=[manage_msg, key_df])
99
- delete_btn.click(do_delete, inputs=manage_key_in, outputs=[manage_msg, key_df])
100
 
101
  demo.launch()
 
7
  )
8
 
9
  # ── Load your private HF model ────────────────────────────────────────────────
10
+ HF_TOKEN = os.environ.get("HF_TOKEN")
11
  MODEL_ID = "Wardline/CLOAK_V2.2.7"
12
 
13
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, token=HF_TOKEN)
14
  model = AutoModelForTokenClassification.from_pretrained(MODEL_ID, token=HF_TOKEN)
15
  ner_pipe = pipeline("ner", model=model, tokenizer=tokenizer, aggregation_strategy="simple")
16
 
17
+ # ── Stitcher: merge split sub-word tokens ─────────────────────────────────────
18
+ def stitch_entities(raw_entities: list) -> list:
19
+ merged = []
20
+ for r in raw_entities:
21
+ if (merged
22
+ and merged[-1]["entity_group"] == r["entity_group"]
23
+ and merged[-1]["end"] == r["start"]):
24
+ merged[-1]["word"] += r["word"].replace(" ", "")
25
+ merged[-1]["end"] = r["end"]
26
+ else:
27
+ merged.append(dict(r)) # copy so we don't mutate the original
28
+ return merged
29
+
30
  # ── PII detection ─────────────────────────────────────────────────────────────
31
  def detect_pii(text: str, api_key: str) -> dict:
32
  entry = validate_key(api_key)
33
  if not entry:
34
  return {"error": "Invalid or revoked API key.", "entities": []}
35
  increment_usage(api_key)
36
+
37
+ raw = ner_pipe(text)
38
+ entities = stitch_entities(raw)
39
+
40
  return {
41
  "text": text,
42
  "entities": [
 
45
  "word": e["word"],
46
  "score": round(e["score"], 4),
47
  "start": e["start"],
48
+ "end": e["end"],
49
  }
50
  for e in entities
51
+ ],
52
  }
53
 
54
  # ── Key management helpers ────────────────────────────────────────────────────
 
66
 
67
  def do_revoke(full_key):
68
  revoke_key(full_key.strip())
69
+ return "Key revoked.", get_key_table()
70
 
71
  def do_delete(full_key):
72
  delete_key(full_key.strip())
73
+ return "Key deleted.", get_key_table()
74
 
75
  # ── Gradio UI ─────────────────────────────────────────────────────────────────
76
  with gr.Blocks(title="PII Detection API") as demo:
 
81
  api_key_in = gr.Textbox(label="API key", placeholder="pii_sk_...")
82
  text_in = gr.Textbox(label="Input text", lines=4,
83
  placeholder="Enter text to scan for PII...")
84
+ detect_btn = gr.Button("Detect PII", variant="primary")
85
  output_json = gr.JSON(label="Results")
86
+ detect_btn.click(fn=detect_pii, inputs=[text_in, api_key_in], outputs=output_json)
 
 
 
 
87
 
88
  with gr.Tab("API Key Management"):
89
  gr.Markdown("### Create a new key")
90
  with gr.Row():
91
+ label_in = gr.Textbox(label="Key label", placeholder="e.g. production")
92
  create_btn = gr.Button("Generate key")
93
  create_msg = gr.Textbox(label="New key (copy now!)", interactive=False, lines=2)
94
 
 
96
  key_df = gr.DataFrame(
97
  value=get_key_table(),
98
  headers=["Label", "Key preview", "Status", "Usage", "Created"],
99
+ interactive=False,
100
  )
101
 
102
  gr.Markdown("### Revoke or delete a key")
 
106
  delete_btn = gr.Button("Delete", variant="stop")
107
  manage_msg = gr.Textbox(label="Result", interactive=False)
108
 
109
+ create_btn.click(create_key, inputs=label_in, outputs=[create_msg, key_df])
110
+ revoke_btn.click(do_revoke, inputs=manage_key_in, outputs=[manage_msg, key_df])
111
+ delete_btn.click(do_delete, inputs=manage_key_in, outputs=[manage_msg, key_df])
112
 
113
  demo.launch()