-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
87 lines (73 loc) · 2.83 KB
/
Copy pathmain.py
File metadata and controls
87 lines (73 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
from fastapi import FastAPI
from pydantic import BaseModel
import spacy
import re
import pandas as pd
# Lade das deutsche Sprachmodell
nlp = spacy.load("de_core_news_md")
app = FastAPI()
# Whitelist für harmlose Wörter, die nicht ersetzt werden sollen
whitelist = {"hallo", "hi", "servus", "hey", "guten tag", "moin", "Guten Morgen", "Guten Mittag", "Guten Abend"}
class TextInput(BaseModel):
text: str
@app.post("/anonymize")
async def anonymize(input: TextInput):
text = input.text
doc = nlp(text)
replacements = []
# spaCy-NER
for ent in doc.ents:
original = ent.text
replacement = None
# Whitelist prüfen
if original.lower().strip() in whitelist:
continue
if ent.label_ == "PER":
parts = original.split()
if len(parts) == 1:
replacement = "[VORNAME]"
elif len(parts) >= 2:
replacement = "[VORNAME] [NACHNAME]"
else:
replacement = "[NAME]"
elif ent.label_ in ["LOC", "GPE"]:
if "straße" in original.lower() or "str." in original.lower() or "allee" in original.lower():
replacement = "[ADDRESS]"
else:
replacement = "[CITY]"
elif ent.label_ == "MISC":
continue # Ignoriere unklare MISC-Entitäten
else:
replacement = f"[{ent.label_}]"
if replacement:
replacements.append((original, replacement))
# Regex-Muster
regex_patterns = [
(r'[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+', '[EMAIL]'),
(r'(?:(?:\+|00)49|0)[\s\-]?(?:\(?\d{2,5}\)?[\s\-]?)?\d{3,}[\s\-]?\d{3,}', '[PHONE]'),
(r'\b([A-ZÄÖÜ][a-zäöüß]+(?:straße|strasse|Str\.|weg|Allee|Gasse|Platz))\s?\d{1,4}\b', '[ADDRESS]'),
(r'\b\d{5}\b', '[ZIP]'),
(r'\b(?:\d{1,3}\.){3}\d{1,3}\b', '[IP]'),
(r'\b(Bestellnummer|Order ID|Bestellung)[\s#:]*[A-Z0-9-]{5,}\b', '[ORDER_ID]'),
(r'\b(Benutzername|Username|User|Login)[\s:]*[a-zA-Z0-9_.-]{3,}\b', '[USERNAME]'),
(r'\bKunden[- ]?Nr\.?:?\s?\d{4,}\b', '[CUSTOMER_ID]'),
(r'\b\d{8,20}\b', '[ACCOUNT_NR]')
]
for pattern, label in regex_patterns:
matches = re.findall(pattern, text)
for match in matches:
replacements.append((match, label))
# Deduplizieren und sortieren (längere zuerst)
seen = set()
unique_replacements = []
for orig, repl in sorted(replacements, key=lambda x: -len(x[0])):
if orig not in seen:
unique_replacements.append((orig, repl))
seen.add(orig)
# Text ersetzen
for orig, repl in unique_replacements:
text = text.replace(orig, repl)
return {
"anonymized": text,
"replacements": [{"original": o, "replaced_with": r} for o, r in unique_replacements]
}