Werea-KVKK-Lab / app.py
GoktugD's picture
Launch Werea KVKK Lab synthetic-data demo
1afa3db verified
Raw
History Blame Contribute Delete
4.74 kB
from __future__ import annotations
from datetime import datetime, timezone
import json
from pathlib import Path
import sys
import gradio as gr
ROOT = Path(__file__).resolve().parent
sys.path.insert(0, str(ROOT / "src"))
from werea_kvkk.engine import PrivacyOpsEngine
from werea_kvkk.governance import OrganisationProfile
from werea_kvkk.pii import PIIDetector
from werea_kvkk.rag import SourceRetriever
detector = PIIDetector()
engine = PrivacyOpsEngine()
retriever = SourceRetriever()
def scan(text: str):
redacted, findings = detector.redact(text)
return redacted, json.dumps([item.to_dict() for item in findings], ensure_ascii=False, indent=2)
def workflow(rule_id: str):
case = engine.create_case(rule_id, datetime.now(timezone.utc))
return json.dumps(case.to_dict(), ensure_ascii=False, indent=2)
def sources(query: str):
return json.dumps(retriever.search(query), ensure_ascii=False, indent=2)
def coverage():
rules = engine.list_rules()
by_tag: dict[str, int] = {}
for item in rules:
for tag in item.get("tags", []):
by_tag[tag] = by_tag.get(tag, 0) + 1
return json.dumps({
"catalog_version": engine.version,
"workflow_count": len(rules),
"source_count": len(retriever.sources),
"by_tag": dict(sorted(by_tag.items())),
"legal_compliance_determination": "not_performed",
"human_legal_review_required": True,
}, ensure_ascii=False, indent=2)
def profile_assessment(sector: str, flags: list[str]):
profile = OrganisationProfile(
organisation_id="synthetic-demo",
legal_name="Kurgusal Kurum",
sectors=(sector,),
established_in_turkiye=True,
processes_special_category_data="Özel nitelikli veri" in flags,
processes_children_data="Çocuk verisi" in flags,
uses_biometric_data="Biyometri" in flags,
uses_ai_for_people="Kişiler hakkında AI" in flags,
has_international_transfers="Yurt dışı aktarım" in flags,
uses_online_tracking="Çerez/SDK" in flags,
)
tags = profile.risk_tags()
applicable = [item["id"] for item in engine.list_rules() if tags.intersection(item.get("tags", []))]
return json.dumps({
"risk_tags": sorted(tags),
"candidate_workflows": applicable,
"notice": "Bu bir ön kapsam önerisidir; hukuki kapsam kararı değildir.",
}, ensure_ascii=False, indent=2)
with gr.Blocks(title="Werea KVKK PrivacyOps v2") as demo:
gr.Markdown("""# Werea KVKK Lab
Evidence-first, human-approved KVKK PrivacyOps v2 research preview.
**Use synthetic text only.** This demo is decision support, not legal advice. It never sends notifications,
submits VERBİS records or deletes data.
""")
with gr.Tab("PII scan"):
input_text = gr.Textbox(label="Synthetic Turkish text", lines=6, value="Ada Örnek'e ada@example.invalid veya 0555 000 12 34 üzerinden ulaşın.")
scan_button = gr.Button("Scan and redact")
redacted = gr.Textbox(label="Redacted")
findings = gr.Code(label="Findings", language="json")
scan_button.click(scan, input_text, [redacted, findings])
with gr.Tab("Workflow"):
rule = gr.Dropdown(choices=[item["id"] for item in engine.list_rules()], value="DSAR_RESPONSE", label="Rule")
workflow_button = gr.Button("Create draft case")
workflow_output = gr.Code(language="json")
workflow_button.click(workflow, rule, workflow_output)
with gr.Tab("Official sources"):
query = gr.Textbox(value="veri ihlali 72 saat", label="Query")
source_button = gr.Button("Search versioned source index")
source_output = gr.Code(language="json")
source_button.click(sources, query, source_output)
with gr.Tab("Coverage"):
gr.Markdown("51 workflow catalog and institution-specific preliminary scoping. No compliance score is produced.")
coverage_button = gr.Button("Show catalog coverage")
coverage_output = gr.Code(language="json")
coverage_button.click(coverage, outputs=coverage_output)
sector = gr.Dropdown(
choices=["retail", "digital", "finance", "health", "employment", "public"],
value="digital",
label="Synthetic organisation sector",
)
flags = gr.CheckboxGroup(
choices=["Özel nitelikli veri", "Çocuk verisi", "Biyometri", "Kişiler hakkında AI", "Yurt dışı aktarım", "Çerez/SDK"],
label="Processing features",
)
profile_button = gr.Button("Build preliminary scope")
profile_output = gr.Code(language="json")
profile_button.click(profile_assessment, [sector, flags], profile_output)
demo.launch()