cjeu-py
The Court of Justice of the European Union has produced thousands of decisions since its creation. Understanding how it builds legal doctrine – which cases it cites, how it treats its own precedent, which areas of law are connected and which remain siloed – requires processing a corpus too large for manual analysis. cjeu-py is a Python toolkit that transforms CJEU case law into research-ready datasets, from raw SPARQL queries to interactive citation networks.
The tool queries the EU Publications Office's CELLAR endpoint directly – the authoritative source for EU legal data – downloads full judgment texts, and extracts citations with a four-phase, footnote-aware extractor that resolves each reference to a CELEX identifier with an explicit confidence tier. Since v0.6.0 it also speaks to the Court's new InfoCuria portal: live search with facets, pending cases, procedural histories, hearing calendars, and the doctrine attached to each case. The result is a complete data pipeline that takes a researcher from zero to interactive network visualisation in a few commands.
I. The Pipeline
cjeu-py organises CJEU research into seven stages. Each stage produces inspectable intermediate output – Parquet tables, JSONL files, HTML visualisations – and can be run independently. The pipeline is resumable: interrupted downloads pick up where they left off, and classification checkpoints prevent re-processing.
Figure 1: The cjeu-py data pipeline. Seven stages from SPARQL query to interactive network.
The design philosophy is pragmatic. Data comes from official sources (CELLAR SPARQL and REST, and the InfoCuria API), not fragile page scraping. Downloads are cached to disk and resumable. The tool is pip-installable (pip install cjeu-py) and runs entirely from the command line, with a browser GUI (cjeu-py gui) for those who prefer one. An LLM layer is optional; the collection, extraction, and network stages work without any API key.
II. What It Collects
For the Grand Chamber alone – the CJEU's most authoritative formation – the tool collects 1,020 decisions spanning 2004 to 2025. Each decision carries rich metadata: CELEX and ECLI identifiers, date, court formation, judge-rapporteur, advocate general, procedure type, subject matter, and the full text of the judgment.
Figure 2: Grand Chamber decisions by year, 2004–2025. Colour indicates the dominant procedure type each year.
Preliminary references dominate the Grand Chamber docket (64%), followed by annulment actions (10%) and consultations (8%). But the procedure mix tells only part of the story. The subject-matter distribution reveals which areas of EU law the Grand Chamber considers important enough for its attention.
Figure 3: Top 10 subject-matter categories across Grand Chamber decisions. Cases may be assigned multiple subjects.
III. Citation Extraction
The heart of the pipeline is citation extraction, and v0.6.0 rebuilt it around a simple observation: the Court's own XHTML already links most case references to their targets. Four phases run in order of confidence. First, CourtLink hyperlinks are read directly from the markup, each carrying an exact ECLI. Second, a catalogue-guided search looks for every case the CELLAR citation graph says the document should cite. Third, a 13-pattern regex safety net catches formal references the structural layers missed. Fourth, an optional party-name enrichment hunts for informal mentions. Every citation is resolved to a CELEX identifier with an explicit confidence tier, from A (exact identifier) to U (honestly unresolved), and each document's recall is scored against the Court's own citation graph.
Two details matter for anyone studying the Advocates General. Extraction is footnote-aware – AG opinions place the overwhelming majority of their citations in footnotes, which naive parsers silently discard – and textual pinpoints (“point 26”, “paragraphs 9 and 10”) are attached to the citations they qualify. Each citation is anchored to its source paragraph or footnote, preserving the context needed for downstream analysis. For the Grand Chamber corpus, CELLAR's own citation graph records 12,673 case-to-case citation edges – roughly 12 per decision, though the distribution is heavily right-skewed – and the extractor's per-document recall is scored against exactly that graph.
IV. The New CURIA Portal
In January 2026 the Court replaced its long-standing InfoCuria search with a new portal, to loud complaints from practitioners. Whatever its merits as a website, the new portal exposes something researchers never had: a clean JSON backend. cjeu-py 0.6.0 ships what is, to our knowledge, the first dedicated Python client for the new InfoCuria search API. It offers live full-text search with facets (document type, jurisdiction, dates), procedural records including pending cases, hearing calendars, judge-rapporteur and advocate general assignments, and the academic doctrine notes the Court curates for each case – none of which the traditional bulk sources expose.
A single command, cjeu-py case C-311/18, merges the CELLAR and CURIA records for any case into one card: identifiers, dates, state, formation, rapporteur, advocate general, referring court, hearings, and doctrine. The client is polite by design – one request per second, an identifying user agent, and payloads pinned against captured fixtures so that silent API drift breaks a test rather than a dataset.
V. How the Court Uses Precedent
Raw citation counts reveal who cites whom, but not how. A companion research programme uses LLMs to classify every citation – stance towards the cited case, depth of engagement, argumentative function – along dimensions drawn from Marc Jacob's Precedents and Case-Based Reasoning in the European Court of Justice (Cambridge, 2014), applied to the datasets cjeu-py produces. That study compares how the Court and its Advocates General construct the case law, across hundreds of matched judgment–opinion pairs. The classification module and the findings ship together with the forthcoming paper; this page will be updated when it is out.
VI. The Citation Network
The extracted citations form a directed graph: each node is a decision, each edge a citation from one case to another. Network analysis reveals structure invisible to close reading.
Figure 5: The ten most-cited Grand Chamber decisions by in-degree (number of times cited by other Grand Chamber cases).
Kadi (2008) leads with 33 citations – the Court's landmark judgment on fundamental rights review of Security Council sanctions has become a touchstone across EU law. Opinion 2/13 (2014), on the EU's accession to the ECHR, follows with 32. Åkerberg Fransson (2013), which defined the scope of the Charter of Fundamental Rights, comes third with 28.
Louvain community detection identifies 51 distinct clusters in the network – doctrinal communities where cases cite each other densely but cite outside the cluster rarely. These clusters map recognisably onto areas of EU law: competition, free movement, fundamental rights, institutional questions, state aid.
The full interactive network – 500 Grand Chamber nodes, filterable by year, procedure, subject, and court – is available as a standalone visualisation.
View Interactive Grand Chamber Network →
VII. What It Enables
cjeu-py is not a finished analysis – it is infrastructure for analyses. The data it produces enables questions that were previously intractable at scale:
Which areas of EU law are most interconnected? Do competition and free movement cases cite each other, or do they develop in isolation? How does the Court's citation practice change when the Grand Chamber, rather than a chamber of five, decides? Do advocate general opinions systematically differ from judgments in how they treat precedent? When the Court distinguishes rather than follows a case, is the distinction genuine or cosmetic? Which judges sit on which cases, and does composition correlate with citation patterns?
The tool is open source and designed for researchers who may not be programmers. A five-command pipeline from zero to interactive network. Parquet tables that open in any data tool. CSV and Excel export with codebooks. Interactive HTML visualisations that run in any browser with no server. And for those working with AI assistants, a read-only MCP server (cjeu-py mcp) lets Claude and other agents query a local corpus – and look up live procedural records – without being able to modify any of it.
Install: pip install cjeu-py
Code: github.com/niccoloridi/cjeu-py
PyPI: pypi.org/project/cjeu-py
Sample data: a frozen 14-document corpus with provenance manifest