EU Models

EU case models extend the base types with typed fields for EU legislative data. Each EU model inherits all base fields (title, identifiers, date, etc.) and adds domain-specific properties drawn from the EU's Common Data Model (CDM).

Members are labelled automatically by origin and kind:

Origin: base inherited from a base model, overridden base interface re-implemented with EU logic, EU specific to the EU case.

Kind: field data attribute (present in the dataset), property computed value derived from other fields, method programmatic interface.

Fields that declare a controlled vocabulary (x_known_values) are soft-validated on construction. Unknown values produce a UserWarning rather than raising an exception, so unexpected data is flagged without blocking processing.

Data provenance

EU model fields are populated from RDF data extracted from the EU Publications Office's Cellar repository. The extraction pipeline uses openbasement templates that map CDM ontology properties to flat Python dicts. The from_openbasement() classmethods on each EU model then map these dicts into typed model instances.

Each EU-specific field declares its openbasement source in the x_source metadata annotation (e.g., source="openbasement:eu_procedure.procedure_type"). This traces the field back to the openbasement template field it was extracted from. A single openbasement template field may source from multiple CDM/RDF predicates.

EUProcedure

Overview

Bases: Procedure

Inherits from Procedure: title, start_date, adoption_date, end_date
Inherits from Entity: identifiers

An EU legislative procedure with typed domain-specific fields.

Extends the base Procedure with known EU fields that carry rich metadata (variable type, controlled vocabularies, data source provenance). The events list uses the EU-specific subtype.

Overrides the base start_event, adoption_event, and status properties with EU-specific event type matching.

Fields:

Details

eventsoverriddenfield pydantic-field

Events in this EU legislative procedure.

procedure_type = NoneEUfield pydantic-field

Source: openbasement template eu_procedure, field procedure_type

Type of EU legislative procedure.

subject_mattersEUfield pydantic-field

Source: openbasement template eu_procedure, field subject_matters

EuroVoc subject matter URIs associated with this procedure.

Source: openbasement template eu_procedure, field basis_legal

Legal basis URI for this procedure.

year_procedure = NoneEUfield pydantic-field

Source: openbasement template eu_procedure, field year_procedure

Year component of the procedure reference number.

number_procedure = NoneEUfield pydantic-field

Source: openbasement template eu_procedure, field number_procedure

Sequence number component of the procedure reference.

date = NoneEUfield pydantic-field

Source: openbasement template eu_procedure, field date

Date associated with this procedure (typically the latest significant event).

start_eventoverriddenproperty property

The Commission proposal event that initiated this procedure.

Looks for known proposal event types. Falls back to the earliest event by date if no proposal event is found.

adoption_eventoverriddenproperty property

The event where the legislative text was formally adopted.

Looks for formal adoption or signature events. Returns None if the procedure has not (yet) been adopted.

end_eventoverriddenproperty property

Terminal event: adoption or withdrawal, whichever applies.

withdrawal_eventEUproperty property

The event where the procedure was withdrawn by the Commission.

Returns None if the procedure has not been withdrawn.

withdrawal_dateEUproperty property

Date when the procedure was withdrawn, or None.

statusoverriddenproperty property

EU procedure status: adopted, withdrawn, or ongoing.

identifiersbasefield pydantic-field

Multi-scheme identifiers for this entity (e.g., CELEX, ELI, Cellar, etc. in the EU case).

title = Nonebasefield pydantic-field

Procedure title, potentially in multiple languages.

start_datebaseproperty property

Date when this procedure started.

adoption_datebaseproperty property

Date when the legislative text was adopted, or None.

end_datebaseproperty property

Date when this procedure concluded, or None if still ongoing.

from_openbasement(data)EUmethod classmethod

Map an openbasement eu_procedure result to an EUProcedure.

Core fields (title, date, identifiers) are mapped to typed model fields. EU-specific fields with declared metadata become typed attributes. Remaining domain-specific fields become extra attributes. Source metadata (_rdf_types, _raw_triples) goes to _raw.

duration(reference_date=None)basemethod

Number of days between start and end of this procedure.

For concluded procedures, returns days between start_date and end_date. For ongoing procedures, uses reference_date as the end point. If reference_date is None, defaults to today.

Returns None if start_date is missing.

Note: in the future, reference_date could default to a collection/download date once that field is implemented.

get_all_documents()basemethod

Collect all documents from all events in this procedure.

EUEvent

Overview

Bases: Event

Inherits from Event: date, title, type
Inherits from Entity: identifiers

An event within an EU legislative process.

Extends the base Event with known EU-specific fields. The documents list uses EUDocument instead of the base Document type.

Documents are populated from three openbasement sources:

  1. documents -- entities from cdm:event_legal_contains_work (structured RDF entities with URI, title, date, resource type).
  2. works -- entities from cdm:event_contains_work (same shape as documents, mapped identically).
  3. document_reference -- literal strings from cdm:event_legal_document_reference (e.g. "COM/2020/319/FINAL"). These become stub documents with a doc_ref identifier scheme.

Sources 1 and 2 may overlap with source 3 for the same underlying document. Deduplication happens later when full document metadata (from separate per-document RDF extraction) is available.

Fields:

Details

documentsoverriddenfield pydantic-field

Documents associated with this EU event.

initiated_by_institution = NoneEUfield pydantic-field

Source: openbasement template eu_procedure, field initiated_by_institution

Institution that initiated this event.

occurs_in_phase = NoneEUfield pydantic-field

Source: openbasement template eu_procedure, field occurs_in_phase

Legislative phase in which this event occurs.

identifiersbasefield pydantic-field

Multi-scheme identifiers for this entity (e.g., CELEX, ELI, Cellar, etc. in the EU case).

date = Nonebasefield pydantic-field

Date when this event occurred (ISO 8601).

title = Nonebasefield pydantic-field

Event title, potentially in multiple languages.

type = Nonebasefield pydantic-field

Event type code.

from_openbasement(data)EUmethod classmethod

Map an openbasement event dict to an EUEvent.

EUDocument

Overview

Bases: Document

Inherits from Document: title, date
Inherits from Entity: identifiers

A document within an EU legislative process.

Extends the base Document with known EU-specific fields. Unknown extra fields are still accepted via extra="allow" inheritance.

Fields:

Details

doc_number = NoneEUfield pydantic-field

Source: openbasement template eu_document, field celex

Document number assigned by the issuing institution.

identifiersbasefield pydantic-field

Multi-scheme identifiers for this entity (e.g., CELEX, ELI, Cellar, etc. in the EU case).

title = Nonebasefield pydantic-field

Document title, potentially in multiple languages.

date = Nonebasefield pydantic-field

Date associated with this document (ISO 8601).

from_openbasement(data)EUmethod classmethod

Map an openbasement document dict to an EUDocument.

Usage

from openstage.models.eu import EUProcedure

# From openbasement extraction results
proc = EUProcedure.from_openbasement(data)

# Base fields (inherited)
proc.title["en"]                    # Multilingual title
proc.identifiers.get("celex")       # CELEX identifier
proc.events                         # List of EUEvent objects
proc.get_all_documents()            # All documents across all events

# EU-specific fields
proc.procedure_type                 # "OLP", "CNS", etc.
proc.subject_matters                # List of EuroVoc URIs
proc.basis_legal                    # Legal basis URI
proc.year_procedure                 # "2021"
proc.number_procedure               # "0381"
proc.date                           # Procedure date

# Researcher interface (EU-specific overrides)
proc.start_event                    # Commission proposal event
proc.start_date                     # Date of proposal
proc.adoption_event                 # Formal adoption event (or None)
proc.adoption_date                  # Date of adoption (or None)
proc.withdrawal_event               # Withdrawal event (or None)
proc.withdrawal_date                # Date of withdrawal (or None)
proc.end_event                      # Terminal event: adoption or withdrawal
proc.end_date                       # Date procedure concluded (or None)
proc.duration()                     # Days from start to end (or to today if ongoing)
proc.duration("2025-01-01")         # Days from start to a reference date
proc.status                         # "adopted", "withdrawn", or "ongoing"

Adapter

The EU adapter maps openbasement flat dicts into typed EU models. EUProcedure.from_openbasement() calls EUEvent.from_openbasement(), which calls EUDocument.from_openbasement().

Map an openbasement eu_procedure result to a Procedure.

Delegates to EUProcedure.from_openbasement() which returns typed EU models. EUProcedure is a subclass of Procedure, so this is backward compatible.

Codebook

The field metadata embedded in eu models can be extracted as a codebook. See Fields and Codebooks for the full documentation.

from openstage.models.codebook import extract_codebook, codebook_to_markdown
from openstage.models.eu.procedure import EUProcedure

entries = extract_codebook(EUProcedure)
print(codebook_to_markdown(entries))