"""Gradio app showing the original rechtspraak texts and the GPT-NL versions side by side."""
import difflib
import html
import random
import re
from collections import defaultdict
import gradio as gr
from datasets import load_dataset
N = 1000
GPTNL_REPO = 'GPT-NL/GPT-NL_Public_Corpus'
DIRECT_REPO = 'sheggle/dutch-legal-documents'
# Stream instead of downloading the full datasets (~10 GB of parquet).
# Copies of an ECLI are adjacent (max 3), so read 2 extra rows to catch spill-over past row N
gptnl = list(load_dataset(GPTNL_REPO, 'rechtspraak', split='train', streaming=True).take(N + 2))
wanted = {doc['source'] for doc in gptnl[:N]}
# Only fetch the source rows we need, filtered on the parquet side
direct = load_dataset(DIRECT_REPO, split='train', streaming=True,
filters=[('identifier', 'in', sorted(wanted))])
direct_docs = {doc['identifier']: doc for doc in direct}
# One ECLI can occur in several (adjacent) GPT-NL rows: collect all of them
gptnl_rows = defaultdict(list)
for i, doc in enumerate(gptnl):
if doc['source'] in wanted and doc['source'] in direct_docs:
gptnl_rows[doc['source']].append((i, doc))
eclis = list(gptnl_rows)
STYLE = """
"""
def diff(left, right):
"""Word-level diff; returns (left html, right html, similarity)."""
# Tokens are words plus their trailing whitespace, so newlines survive; compare on the words only
lt, rt = re.findall(r'\S+\s*', left), re.findall(r'\S+\s*', right)
sm = difflib.SequenceMatcher(None, [t.rstrip() for t in lt], [t.rstrip() for t in rt])
l_html, r_html = [], []
for tag, i1, i2, j1, j2 in sm.get_opcodes():
l_chunk = html.escape(''.join(lt[i1:i2]))
r_chunk = html.escape(''.join(rt[j1:j2]))
if tag == 'equal':
l_html.append(l_chunk)
r_html.append(r_chunk)
else:
if l_chunk:
l_html.append(f'{l_chunk}')
if r_chunk:
r_html.append(f'{r_chunk}')
return ''.join(l_html), ''.join(r_html), sm.ratio()
def ecli_link(ecli):
url = f'https://uitspraken.rechtspraak.nl/details?id={ecli}'
return f'{html.escape(ecli)}'
def repo_link(repo):
return f'{repo}'
def header(tag, title, *meta):
"""One-line header; meta items are (label, html) pairs."""
meta = ' · '.join(f'{label} {value}' if label else value for label, value in meta)
return f'<{tag}>{title} {meta}{tag}>'
def render(ecli):
d = direct_docs[ecli]
left = d['full_text']
# Diff every GPT-NL row against the original; the left side shows the diff with the best row
results = [(i, doc, *diff(left, doc['text'])) for i, doc in gptnl_rows[ecli]]
best = max(results, key=lambda r: r[4])
stats = f'
{ecli_link(ecli)} — {len(results)} GPT-NL row(s)
' left_header = header('h3', repo_link(DIRECT_REPO), ('id', html.escape(str(d['id']))), ('', f'{len(left.split()):,} words'), ('', f'diff vs. row {best[0]}')) right_html = ''.join( header('h4', f'Row {i}', ('id', html.escape(doc['id'])), ('', f'{len(doc["text"].split()):,} words'), ('', f'similarity {sim:.3f}')) + f'