Developer guide
EU financial sanctions data in Python: inspect an official XML file
Inspect an official EU sanctions XML snapshot in Python, retain its hash and provenance, and keep structural parsing separate from screening approval.
On this page
Choose the official-data path deliberately
Use the European Commission’s financial sanctions database and official EU dataset page to locate the current downloadable resource. The data portal, legal acts, and normalized third-party coverage are different resources. Do not copy a legacy XML endpoint or schema from an old tutorial and assume it is still the current interface.
SanctionsKit’s published coverage currently describes this source as reference-only. This guide does not invent a selectable API source ID or promise a production screening endpoint for it. It provides a complete local snapshot-inspection utility, not a matching engine or a finished ingestion service.
Download and record the actual provenance
Follow the official authority page to its current XML download. Save the original bytes as snapshot.xml without editing them. Record the exact official HTTPS URL in SOURCE_URL and the actual download time in DOWNLOADED_AT using a UTC ISO timestamp such as YYYY-MM-DDTHH:MM:SSZ.
The script reads a local file and does not fetch arbitrary URLs. A source URL and SHA-256 hash make the captured artifact traceable; neither proves that the operator downloaded authentic data or that the file is complete and current.
Install the parser dependency
Use Python 3.11 or later for this separate data utility, and install the XML dependency below. Save the client as inspect.py. Keep the parser dependency in your own project environment, not the SanctionsKit content folder.
The utility accepts UTF-8 XML, limits input to 50 MiB, rejects DTD and entity declarations, and refuses obvious HTML or error document roots. Other encodings or larger approved feeds need a deliberately reviewed adapter rather than silently bypassing the checks.
python -m pip install "defusedxml>=0.7.1,<0.8"Inspect the snapshot without activating it
Successful output has status parsed_not_approved. It records the bytes, SHA-256, root element, and supplied provenance, but intentionally does not produce potential_match or no_match. A file that parses successfully can still be stale, incomplete, or the wrong source schema.
"""Python 3.11+. pip install defusedxml. Structural inspection, not a matcher."""
import hashlib
import json
import os
import re
import sys
from datetime import datetime
from pathlib import Path
from urllib.parse import urlparse
from defusedxml import ElementTree
def main() -> None:
if len(sys.argv) != 3 or sys.argv[1] not in ("eu", "un"):
raise ValueError("Usage: python inspect.py eu|un snapshot.xml")
authority, filename = sys.argv[1:]
source = urlparse(os.environ["SOURCE_URL"])
host = source.hostname or ""
allowed = host in ("scsanctions.un.org", "main.un.org") if authority == "un" else (host == "europa.eu" or host.endswith(".europa.eu"))
if source.scheme != "https" or source.username or source.password or not allowed:
raise ValueError("Use an approved official HTTPS source URL")
downloaded = os.environ["DOWNLOADED_AT"]
if not re.fullmatch(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z", downloaded):
raise ValueError("Record the actual UTC download timestamp")
datetime.fromisoformat(downloaded.replace("Z", "+00:00"))
path = Path(filename)
limit = 50 * 1024 * 1024
if path.stat().st_size > limit:
raise ValueError("Snapshot exceeds 50 MiB")
raw = path.read_bytes()
if not raw or len(raw) > limit or b"\x00" in raw:
raise ValueError("Empty, oversized, or unsupported-encoding snapshot")
text = raw.decode("utf-8-sig", errors="strict")
root = ElementTree.fromstring(text, forbid_dtd=True, forbid_entities=True, forbid_external=True)
tag = root.tag.rsplit("}", 1)[-1]
if tag.lower() in ("html", "error"):
raise ValueError("Unexpected document root")
print(json.dumps({
"authority": authority, "sourceUrl": source.geturl(), "downloadedAt": downloaded,
"sha256": hashlib.sha256(raw).hexdigest(), "byteLength": len(raw),
"rootElement": root.tag, "status": "parsed_not_approved",
"checksStillRequired": ["source authenticity", "current source schema", "record identifiers", "completeness", "normalization", "matching tests"],
}, indent=2))
if __name__ == "__main__":
try:
main()
except Exception:
print("Snapshot inspection failed. Keep the previous approved dataset active.", file=sys.stderr)
sys.exit(1)Run and retain the inspection manifest
Set SOURCE_URL and DOWNLOADED_AT to the actual recorded values, then run the command below. Save the manifest with the original snapshot. Keep the previously approved dataset active if a new file fails inspection; a failed refresh must not publish an empty sanctions dataset.
python inspect.py eu snapshot.xml > snapshot-manifest.jsonDefine source-specific normalization before matching
For an EU adapter, review the current source structure for record identifiers, names and aliases, dates, addresses, regulation references, and source language. Document namespace handling and preserve the original reference to the legal measure. This tutorial deliberately does not invent a current EU XML schema or claim a complete production normalizer.
Before activating an ingestion adapter, validate its current schema, check required identifiers, compare counts and changes with the prior approved version, and test normalization on representative records. Keep the full original snapshot for reconstruction under your approved handling policy.
Build the next controls explicitly
Matching, review, freshness enforcement, and legal interpretation remain separate work. A successful parser cannot determine whether a customer is the listed identity or whether a proposed activity is authorized. See the data-freshness guide for the difference between downloaded, parsed, approved, and active data.
- Test empty files, truncated XML, HTML responses, and forbidden declarations.
- Test namespaces, Unicode names, partial dates, and repeatable snapshot hashes.
- Document the expected schema before accepting a new source version.
- Keep refresh failures visible and preserve the prior approved dataset.
- Do not report unsupported API coverage as a successful screening.