sid570 commited on
Commit
4ed16e0
·
verified ·
1 Parent(s): 68fdc92

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -69
app.py CHANGED
@@ -2,24 +2,6 @@ import re
2
  import gradio as gr
3
  from entity_dictionary import ENTITY_DICTIONARY
4
 
5
- # ============================================================
6
- # 🔢 CATEGORY PRIORITY
7
- # ============================================================
8
- CATEGORY_PRIORITY = {
9
- "DISTRICT": 1,
10
- "CITY": 2,
11
- "VILLAGE": 3,
12
- "LANDMARK": 4,
13
- "PERSON": 5,
14
- "PRODUCT": 6,
15
- "TIME": 7,
16
- "DATE": 8,
17
- "PHONE": 9,
18
- "MONEY": 10,
19
- "NUMBER": 11,
20
- "UNKNOWN": 50
21
- }
22
-
23
  # ============================================================
24
  # 🔹 TOKENIZATION
25
  # ============================================================
@@ -27,75 +9,106 @@ def tokenize(text):
27
  return re.findall(r"\w+|[.!?]", text)
28
 
29
  # ============================================================
30
- # 🔍 BUILD LOWERCASED DICTIONARY LOOKUP
 
31
  # ============================================================
32
- def build_dictionary_lookup():
33
- lookup = {}
34
- for category, words in ENTITY_DICTIONARY.items():
35
- if category == "REGEX_PATTERNS":
36
- continue
37
- for w in words:
38
- lookup[w.lower()] = category
39
- return lookup
40
 
41
- DICT_LOOKUP = build_dictionary_lookup()
 
 
 
42
 
43
  # ============================================================
44
- # 🧠 ENTITY DETECTION (FINAL RULE SET)
45
  # ============================================================
46
  def detect_entities(text):
47
  tokens = tokenize(text)
48
  entities = []
49
 
50
  i = 0
 
 
51
  while i < len(tokens):
52
  token = tokens[i]
53
 
 
 
 
 
 
 
54
  if not token.isalpha():
55
  i += 1
56
  continue
57
 
58
  # ====================================================
59
- # 1️⃣ LOWERCASE WORD RULE
60
  # ====================================================
61
- if token[0].islower():
62
- key = token.lower()
63
- if key in DICT_LOOKUP:
 
64
  entities.append({
65
- "text": token,
66
- "type": DICT_LOOKUP[key]
67
  })
68
- i += 1
 
 
 
 
69
  continue
70
 
71
  # ====================================================
72
- # 2️⃣ UPPERCASE WORD RULE (GROUPING)
73
  # ====================================================
74
- phrase = [token]
75
- j = i + 1
76
-
77
- while (
78
- j < len(tokens)
79
- and tokens[j].isalpha()
80
- and tokens[j][0].isupper()
81
- ):
82
- phrase.append(tokens[j])
83
- j += 1
84
 
85
- phrase_text = " ".join(phrase) # original casing
86
- phrase_key = phrase_text.lower() # ✅ LOWERCASED FOR LOOKUP
87
-
88
- if phrase_key in DICT_LOOKUP:
89
- etype = DICT_LOOKUP[phrase_key]
90
- else:
91
- etype = "UNKNOWN"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
- entities.append({
94
- "text": phrase_text,
95
- "type": etype
96
- })
 
 
 
 
 
 
97
 
98
- i = j # move past grouped phrase
99
 
100
  return entities
101
 
@@ -105,10 +118,6 @@ def detect_entities(text):
105
  def detect_and_mask(text):
106
  entities = detect_entities(text)
107
 
108
- entities.sort(
109
- key=lambda e: (CATEGORY_PRIORITY.get(e["type"], 999), -len(e["text"]))
110
- )
111
-
112
  masked = text
113
  entity_map = {}
114
  counters = {}
@@ -136,16 +145,15 @@ def detect_and_mask(text):
136
  # 🔓 UNMASKING
137
  # ============================================================
138
  def unmask_entities(masked_text, entity_map):
139
- restored = masked_text
140
- for ph in sorted(entity_map, key=len, reverse=True):
141
- restored = restored.replace(ph, entity_map[ph])
142
- return restored
143
 
144
  # ============================================================
145
  # 🖥️ GRADIO UI
146
  # ============================================================
147
  with gr.Blocks() as demo:
148
- gr.Markdown("# 🧠 Entity Detection & Masking API")
149
 
150
  with gr.Tab("Detect & Mask"):
151
  text_in = gr.Textbox(label="Input Text")
@@ -159,4 +167,4 @@ with gr.Blocks() as demo:
159
  gr.Button("Unmask").click(unmask_entities, [masked, entity_map], out)
160
 
161
  demo.queue()
162
- demo.launch()
 
2
  import gradio as gr
3
  from entity_dictionary import ENTITY_DICTIONARY
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  # ============================================================
6
  # 🔹 TOKENIZATION
7
  # ============================================================
 
9
  return re.findall(r"\w+|[.!?]", text)
10
 
11
  # ============================================================
12
+ # 🔍 DICTIONARY LOOKUP (case-insensitive, multi-word)
13
+ # RETURNS (category, length, text) OR None
14
  # ============================================================
15
+ def find_dictionary_match(tokens, start):
16
+ for category, phrases in ENTITY_DICTIONARY.items():
17
+ for phrase in phrases:
18
+ p_tokens = phrase.split()
19
+ span = tokens[start:start + len(p_tokens)]
20
+
21
+ if len(span) != len(p_tokens):
22
+ continue
23
 
24
+ if [t.lower() for t in span] == [p.lower() for p in p_tokens]:
25
+ return category, len(p_tokens), " ".join(span)
26
+
27
+ return None
28
 
29
  # ============================================================
30
+ # 🧠 ENTITY DETECTION FINAL RULESET
31
  # ============================================================
32
  def detect_entities(text):
33
  tokens = tokenize(text)
34
  entities = []
35
 
36
  i = 0
37
+ sentence_start = True
38
+
39
  while i < len(tokens):
40
  token = tokens[i]
41
 
42
+ # Sentence boundary
43
+ if token in [".", "!", "?"]:
44
+ sentence_start = True
45
+ i += 1
46
+ continue
47
+
48
  if not token.isalpha():
49
  i += 1
50
  continue
51
 
52
  # ====================================================
53
+ # 1️⃣ FIRST WORD
54
  # ====================================================
55
+ if sentence_start:
56
+ match = find_dictionary_match(tokens, i)
57
+ if match:
58
+ category, length, text_val = match
59
  entities.append({
60
+ "text": text_val,
61
+ "type": category
62
  })
63
+ i += length
64
+ else:
65
+ i += 1
66
+
67
+ sentence_start = False
68
  continue
69
 
70
  # ====================================================
71
+ # 2️⃣ UPPERCASE WORDS
72
  # ====================================================
73
+ if token[0].isupper():
 
 
 
 
 
 
 
 
 
74
 
75
+ # Try dictionary match (single or multi-word)
76
+ match = find_dictionary_match(tokens, i)
77
+ if match:
78
+ category, length, text_val = match
79
+ entities.append({
80
+ "text": text_val,
81
+ "type": category
82
+ })
83
+ i += length
84
+ continue
85
+
86
+ # Group consecutive uppercase words
87
+ phrase = [token]
88
+ j = i + 1
89
+ while j < len(tokens) and tokens[j].isalpha() and tokens[j][0].isupper():
90
+ phrase.append(tokens[j])
91
+ j += 1
92
+
93
+ entities.append({
94
+ "text": " ".join(phrase),
95
+ "type": "UNKNOWN"
96
+ })
97
+ i = j
98
+ continue
99
 
100
+ # ====================================================
101
+ # 3️⃣ LOWERCASE WORDS
102
+ # ====================================================
103
+ match = find_dictionary_match(tokens, i)
104
+ if match:
105
+ category, _, text_val = match
106
+ entities.append({
107
+ "text": text_val,
108
+ "type": category
109
+ })
110
 
111
+ i += 1
112
 
113
  return entities
114
 
 
118
  def detect_and_mask(text):
119
  entities = detect_entities(text)
120
 
 
 
 
 
121
  masked = text
122
  entity_map = {}
123
  counters = {}
 
145
  # 🔓 UNMASKING
146
  # ============================================================
147
  def unmask_entities(masked_text, entity_map):
148
+ for k in sorted(entity_map, key=len, reverse=True):
149
+ masked_text = masked_text.replace(k, entity_map[k])
150
+ return masked_text
 
151
 
152
  # ============================================================
153
  # 🖥️ GRADIO UI
154
  # ============================================================
155
  with gr.Blocks() as demo:
156
+ gr.Markdown("# 🧠 Entity Masking API (Dictionary-Driven)")
157
 
158
  with gr.Tab("Detect & Mask"):
159
  text_in = gr.Textbox(label="Input Text")
 
167
  gr.Button("Unmask").click(unmask_entities, [masked, entity_map], out)
168
 
169
  demo.queue()
170
+ demo.launch()