API reference¶
Generated from the docstrings in the source.
This page covers the public API: what import ddi_l exposes and what
semantic versioning applies to. For the wider model layer, see
Models reference for the guided tour and
Schema coverage for what is supported at which level.
Where to start
new_study() and open_ddi() return a Document,
which is the front door. DDIDocument, DDIFragment and StudyCursor are
the advanced layer underneath it. Reach for them when you need to work with
raw elements, partial instances, or a specific study in a multi-study file.
Creating and opening documents¶
Create a new DDI document with a StudyUnit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Human-readable title for the study. |
required |
agency
|
str
|
Maintenance agency responsible for the study. |
required |
identifier
|
str | None
|
Optional identifier; auto-generated if omitted. |
None
|
version
|
str
|
Version string for the study. |
'1'
|
lang
|
str
|
Language tag for the study's title and abstract, and for the labels put on the module and scheme wrappers the helpers generate. |
'en'
|
Returns:
| Name | Type | Description |
|---|---|---|
Document |
Document
|
A new document ready for adding content. |
Example
import ddi_l as ddi doc = ddi.new_study(title="My Survey", agency="example.org")
Open a DDI XML file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Filesystem path to read. |
required |
validate
|
bool
|
Whether to validate against the DDI schema on load. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
Document |
Document
|
The parsed document. |
Example
import ddi_l as ddi doc = ddi.open_ddi("study.xml")
Document¶
Document ¶
A DDI Lifecycle 3.3 document with a simple CRUD API.
This is the primary interface for creating, reading, updating, and deleting content in DDI documents. It manages a single StudyUnit and provides convenience methods for common operations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inner
|
DDIDocument
|
The underlying DDIDocument instance. |
required |
Example
import ddi_l as ddi doc = ddi.new_study(title="My Survey", agency="example.org") q = doc.add_question(text="How old are you?") doc.save("my-study.xml")
title
property
¶
Return the study's citation title, or None when unavailable.
Reads the citation title from the StudyUnit when it carries its own
r:Citation, then the document-level one written by
:func:new_study (and preserved by :func:open_ddi), falling back
last to the StudyUnit's first abstract.
resource_packages
property
¶
list[ResourcePackage]: ResourcePackages on the DDIInstance.
local_holding_packages
property
¶
list[LocalHoldingPackage]: LocalHoldingPackages on the DDIInstance.
translation_information
property
¶
TranslationInformation | None: the instance's translation info.
questions
property
¶
list[QuestionItem]: All questions in the document.
study_unit
property
¶
StudyUnit: The document's active :class:StudyUnit model object.
Use this to reach study-level metadata the CRUD helpers do not cover ---
versioning (:meth:~MaintainableBase.increment_minor_version), version
rationales, custom properties on the study itself.
The object is live: mutating it changes the document, and the changes
are serialized by :meth:save, :meth:to_xml and :meth:validate.
Raises:
| Type | Description |
|---|---|
DDIModelError
|
If the document contains no StudyUnit. |
Example
import ddi_l as ddi doc = ddi.new_study(title="My Survey", agency="example.org") doc.study_unit.increment_minor_version()
inner
property
¶
DDIDocument: The underlying XML-level document, for advanced use.
Accessing it hands the XML tree to the caller: pending edits are
written out and model objects obtained earlier from this
:class:Document are detached, so later XML edits are picked up.
add_question ¶
add_question(
text: str,
*,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
identifier: str | None = None,
) -> QuestionItem
Add a question to the document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The question text. |
required |
lang
|
str
|
Language tag for the text. |
'en'
|
label
|
str | None
|
Optional human-readable label. Supplying one keeps the
document clean under the |
None
|
label_lang
|
str | None
|
Language tag for |
None
|
identifier
|
str | None
|
Optional identifier; auto-generated if omitted. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
QuestionItem |
QuestionItem
|
The newly created question. |
add_variable ¶
add_variable(
name: str,
*,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
question: QuestionItem | Reference | None = None,
concept: Concept | Reference | None = None,
identifier: str | None = None,
) -> Variable
Add a variable to the document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The variable name. |
required |
lang
|
str
|
Language tag for the name. |
'en'
|
label
|
str | None
|
Optional human-readable label. Supplying one keeps the
document clean under the |
None
|
label_lang
|
str | None
|
Language tag for |
None
|
question
|
QuestionItem | Reference | None
|
Optional question to link via reference. |
None
|
concept
|
Concept | Reference | None
|
Optional concept to link via reference. |
None
|
identifier
|
str | None
|
Optional identifier; auto-generated if omitted. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
Variable |
Variable
|
The newly created variable. |
add_concept ¶
add_concept(
name: str,
*,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
identifier: str | None = None,
) -> Concept
Add a concept to the document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The concept name. |
required |
lang
|
str
|
Language tag for the name. |
'en'
|
label
|
str | None
|
Optional human-readable label. Supplying one keeps the
document clean under the |
None
|
label_lang
|
str | None
|
Language tag for |
None
|
identifier
|
str | None
|
Optional identifier; auto-generated if omitted. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
Concept |
Concept
|
The newly created concept. |
add_universe ¶
add_universe(
name: str,
*,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
identifier: str | None = None,
) -> Universe
Add a universe to the document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The universe name. |
required |
lang
|
str
|
Language tag for the name. |
'en'
|
label
|
str | None
|
Optional human-readable label. Supplying one keeps the
document clean under the |
None
|
label_lang
|
str | None
|
Language tag for |
None
|
identifier
|
str | None
|
Optional identifier; auto-generated if omitted. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
Universe |
Universe
|
The newly created universe. |
add_code_list ¶
add_code_list(
name: str,
*,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
identifier: str | None = None,
) -> CodeList
Add a code list to the document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The code list name. |
required |
lang
|
str
|
Language tag for the name. |
'en'
|
label
|
str | None
|
Optional human-readable label. Supplying one keeps the
document clean under the |
None
|
label_lang
|
str | None
|
Language tag for |
None
|
identifier
|
str | None
|
Optional identifier; auto-generated if omitted. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
CodeList |
CodeList
|
The newly created code list. |
add_item ¶
add_item(
item_type: type[MaintainableBase],
*,
name: str | None = None,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
identifier: str | None = None,
**kwargs: object,
) -> MaintainableBase
Add an item of any registered type to the document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item_type
|
type[MaintainableBase]
|
The MaintainableBase subclass to create (e.g.
|
required |
name
|
str | None
|
Display name for the item. Passed as |
None
|
lang
|
str
|
Language tag for |
'en'
|
label
|
str | None
|
Optional human-readable label. Supplying one keeps the
document clean under the |
None
|
label_lang
|
str | None
|
Language tag for |
None
|
identifier
|
str | None
|
Optional identifier; auto-generated if omitted. |
None
|
**kwargs
|
object
|
Extra keyword arguments forwarded to the item constructor. |
{}
|
Returns:
| Type | Description |
|---|---|
MaintainableBase
|
An instance of |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
add_record_layout ¶
add_record_layout(
*,
identifier: str | None = None,
logical_record: LogicalRecord | None = None,
) -> RecordLayout
Create a record layout that maps variables to positions in a file.
Builds a backing physical structure and a linked RecordLayout, both
stored on the study and serialized inside a PhysicalDataProduct. Add
variable-to-position mappings on the returned layout with
:meth:RecordLayout.add_data_item::
rl = doc.add_record_layout()
rl.add_data_item(age.to_reference(), start_position=1, width=2)
Pass logical_record (from
:meth:DataRelationship.add_logical_record) to tie the backing physical
structure to that logical record, so the layout describes a modeled
record rather than a placeholder.
Returns:
| Name | Type | Description |
|---|---|---|
RecordLayout |
RecordLayout
|
the new, document-attached record layout. |
add_dataset ¶
add_dataset(
*,
name: str | None = None,
identifier: str | None = None,
lang: str = "en",
) -> DataSet
Create an inline dataset (data values stored in the document).
Add values on the returned dataset with
:meth:DataSet.add_item_value::
ds = doc.add_dataset(name="Sample rows")
ds.add_item_value(age.to_reference(), record="1", value="42")
Returns:
| Name | Type | Description |
|---|---|---|
DataSet |
DataSet
|
the new, document-attached inline dataset. |
add_data_relationship ¶
add_data_relationship(
*,
identifier: str | None = None,
label: str | None = None,
lang: str = "en",
) -> DataRelationship
Create a data relationship in the logical product.
A data relationship groups the dataset's logical records. Add records
with :meth:DataRelationship.add_logical_record::
dr = doc.add_data_relationship()
dr.add_logical_record() # all variables in one rectangular record
Returns:
| Name | Type | Description |
|---|---|---|
DataRelationship |
DataRelationship
|
the new, document-attached data relationship. |
add_ncube ¶
add_ncube(
*,
name: str | None = None,
identifier: str | None = None,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
) -> NCube
Create a multidimensional cube (NCube) in the logical product.
Add axes and measured values on the returned cube::
cube = doc.add_ncube(name="Population by year and region")
cube.add_dimension(year.to_reference())
cube.add_dimension(region.to_reference())
cube.add_measure(population.to_reference())
Returns:
| Name | Type | Description |
|---|---|---|
NCube |
NCube
|
the new, document-attached cube. |
add_group ¶
Organize the document's study into a Group (study series/package).
The StudyUnit is moved under a new <g:Group> in the DDIInstance. The
document stays fully editable: add_variable, add_question, and the
rest still resolve to the now-grouped study. Returns the new Group.
add_ddi_profile ¶
add_ddi_profile(
*,
name: str | None = None,
x_path_version: float = 1.0,
used_xpaths: Iterable[str] | None = None,
identifier: str | None = None,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
) -> DDIProfile
Attach a DDIProfile declaring which DDI elements are used.
Pass used_xpaths for the common case, or call :meth:DDIProfile.add_used
on the returned profile; it is re-serialized on save either way::
profile = doc.add_ddi_profile(name="Deposit profile")
profile.add_used("//s:StudyUnit", is_required=True)
Returns:
| Name | Type | Description |
|---|---|---|
DDIProfile |
DDIProfile
|
the new profile, attached at the DDIInstance level. |
add_study ¶
Add an additional StudyUnit to the document's group (a study series).
The document is organized into a group if it is not already. The new
study is returned for model-layer building; it is re-serialized into the
group on save. To target it with the high-level add_* helpers, use
the cursor from :meth:study::
wave2 = doc.add_study(title="Wave 2")
doc.study(wave2.identifier).add_variable(name="income")
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Title of the new study. |
required |
identifier
|
str | None
|
Optional identifier; generated when omitted. |
None
|
lang
|
str | None
|
Language of |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
StudyUnit |
StudyUnit
|
the new, group-attached study unit. |
study ¶
study(identifier: str | None = None) -> StudyCursor
Return a cursor whose add_* helpers target a specific study.
With no identifier (or the primary study's id) the cursor targets the
primary study; otherwise it targets a study previously added with
:meth:add_study. This is how you edit a non-primary study in a
multi-study series::
doc.study(wave2.identifier).add_variable(name="income")
Returns:
| Name | Type | Description |
|---|---|---|
StudyCursor |
StudyCursor
|
a cursor bound to the resolved study. |
Raises:
| Type | Description |
|---|---|
DDIReferenceError
|
If no study matches |
add_comparison ¶
add_comparison(
*,
name: str | None = None,
identifier: str | None = None,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
) -> Comparison
Add a Comparison (harmonization maps) to the document's group.
Map items across studies/versions on the returned comparison::
cmp = doc.add_comparison(name="2020 to 2021")
cmp.add_variable_map(age_2020.to_reference(), age_2021.to_reference())
Returns:
| Name | Type | Description |
|---|---|---|
Comparison |
Comparison
|
the new, group-attached comparison. |
add_archive ¶
add_archive(
*,
identifier: str | None = None,
label: str | None = None,
lang: str = "en",
) -> Archive
Attach an Archive module to the primary study.
The archive holds archive-specific lifecycle metadata for the study. Populate it further on the returned model object; it is re-serialized on save.
Returns:
| Name | Type | Description |
|---|---|---|
Archive |
Archive
|
the new archive, attached to the primary StudyUnit. |
add_resource_package ¶
Attach a ResourcePackage (reusable metadata) to the DDIInstance.
Returns:
| Name | Type | Description |
|---|---|---|
ResourcePackage |
ResourcePackage
|
the new package, at the DDIInstance level. |
add_local_holding_package ¶
add_local_holding_package(
*,
depository_study_unit: MaintainableBase
| Reference
| None = None,
identifier: str | None = None,
) -> LocalHoldingPackage
Attach a LocalHoldingPackage recording a local holding.
A local holding package references the deposited object it holds. By
default it points at the primary study; pass depository_study_unit to
reference a different study unit.
Returns:
| Name | Type | Description |
|---|---|---|
LocalHoldingPackage |
LocalHoldingPackage
|
the new package, at the DDIInstance level. |
add_translation_information ¶
add_translation_information(
*,
languages: Iterable[str] | None = None,
description: str | None = None,
lang: str = "en",
) -> TranslationInformation
Set the DDIInstance TranslationInformation.
Describes which languages are involved in translating the instance, with an optional description. Replaces any existing translation information.
Returns:
| Name | Type | Description |
|---|---|---|
TranslationInformation |
TranslationInformation
|
the translation information element. |
items ¶
Return all items of item_type in the document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item_type
|
type[MaintainableBase]
|
The MaintainableBase subclass to query (e.g.
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
list |
list[MaintainableBase]
|
All items of the requested type. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
find ¶
Find an item by identifier in any study of the document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
identifier
|
str | None
|
The identifier to search for. |
required |
Returns:
| Type | Description |
|---|---|
Any | None
|
The matching model object, or |
Any | None
|
|
remove ¶
Remove an item by identifier from any study of the document.
References to the removed item elsewhere in the document are left in
place; :meth:validate reports them as dangling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
identifier
|
str | None
|
The identifier of the item to remove. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if an item was removed, False if not found. |
save ¶
Save the document to an XML file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Filesystem path to write to. |
required |
pretty_print
|
bool
|
Format the output for readability. |
True
|
Warns:
| Type | Description |
|---|---|
DDIReferenceWarning
|
If a reference in the study points at an item the document does not contain. |
to_xml ¶
Serialize the document to an XML string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pretty_print
|
bool
|
Format the output for readability. |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
UTF-8 XML representation, including the XML declaration. |
validate ¶
Validate the document against the DDI schema.
Returns:
| Name | Type | Description |
|---|---|---|
list |
list
|
Schema validation issues; empty if valid. |
lint ¶
lint(
rules: Sequence[str] | None = None,
) -> list[LintFinding]
Run the lint rules against the document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rules
|
Sequence[str] | None
|
Rule identifiers to run; |
None
|
Returns:
| Type | Description |
|---|---|
list[LintFinding]
|
list[LintFinding]: Findings; empty when the document is clean. |
StudyCursor¶
StudyCursor ¶
StudyCursor(document: Document, study: StudyUnit)
A handle to one study whose add_* helpers target that study.
Obtained from :meth:Document.study. Each method forwards to the matching
:class:Document helper with this cursor's study as the target, so the same
validation and serialization apply. This is how you edit a non-primary study
in a multi-study series.
add_question ¶
add_question(
text: str,
*,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
identifier: str | None = None,
) -> QuestionItem
Add a question to this study (see :meth:Document.add_question).
add_variable ¶
add_variable(
name: str,
*,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
question: QuestionItem | Reference | None = None,
concept: Concept | Reference | None = None,
identifier: str | None = None,
) -> Variable
Add a variable to this study (see :meth:Document.add_variable).
add_concept ¶
add_concept(
name: str,
*,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
identifier: str | None = None,
) -> Concept
Add a concept to this study (see :meth:Document.add_concept).
add_universe ¶
add_universe(
name: str,
*,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
identifier: str | None = None,
) -> Universe
Add a universe to this study (see :meth:Document.add_universe).
add_code_list ¶
add_code_list(
name: str,
*,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
identifier: str | None = None,
) -> CodeList
Add a code list to this study (see :meth:Document.add_code_list).
add_item ¶
add_item(
item_type: type[MaintainableBase],
*,
name: str | None = None,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
identifier: str | None = None,
**kwargs: object,
) -> MaintainableBase
Add any registered item to this study (see :meth:Document.add_item).
add_ncube ¶
add_ncube(
*,
name: str | None = None,
identifier: str | None = None,
lang: str = "en",
label: str | None = None,
label_lang: str | None = None,
) -> NCube
Add an NCube to this study (see :meth:Document.add_ncube).
add_data_relationship ¶
add_data_relationship(
*,
identifier: str | None = None,
label: str | None = None,
lang: str = "en",
) -> DataRelationship
Add a data relationship (see :meth:Document.add_data_relationship).
add_record_layout ¶
add_record_layout(
*,
identifier: str | None = None,
logical_record: LogicalRecord | None = None,
) -> RecordLayout
Add a record layout (see :meth:Document.add_record_layout).
add_dataset ¶
add_dataset(
*,
name: str | None = None,
identifier: str | None = None,
lang: str = "en",
) -> DataSet
Add an inline dataset (see :meth:Document.add_dataset).
add_archive ¶
add_archive(
*,
identifier: str | None = None,
label: str | None = None,
lang: str = "en",
) -> Archive
Add an archive to this study (see :meth:Document.add_archive).
Reading and writing¶
Parse source into a :class:DDIDocument or :class:DDIFragment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
SourceType
|
The DDI instance XML to parse. Accepts filesystem paths, strings, bytes, or file-like objects. |
required |
validate
|
bool
|
Whether to validate the parsed document against the DDI XML schema. |
False
|
build_index
|
bool
|
Build the resolver index now. By default it is built on
first use of :attr: |
False
|
version
|
str | None
|
Optional DDI schema version override used when validating the parsed document. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
DDIWrapper
|
class: |
DDIWrapper
|
class: |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
Propagated when |
TypeError
|
Raised when |
ValueError
|
Raised when the parsed XML root is not a valid DDI instance or fragment tag. |
DDIReadError
|
Raised when XML parsing fails because the input is malformed or cannot be read. |
Serialize a document to destination (or return bytes when omitted).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
document_or_element
|
DocumentLike
|
A DDI document wrapper, maintainable object, element, or serialized XML that should be emitted as XML. |
required |
destination
|
str | Path | BinaryIO | TextIO | None
|
Optional output location. When |
None
|
pretty_print
|
bool
|
Whether to format the XML output with indentation when supported by the underlying XML backend. |
True
|
xml_declaration
|
bool
|
Whether to include the XML declaration at the start of the serialized output. |
True
|
encoding
|
str
|
Text encoding used when writing XML bytes or decoding to text streams. |
'utf-8'
|
version
|
str | None
|
Optional DDI schema version override used to assert the target release is supported when specified. |
None
|
Returns:
| Type | Description |
|---|---|
bytes
|
The serialized XML bytes regardless of |
Raises:
| Type | Description |
|---|---|
DDIWriteError
|
Raised when serialization or writing to the destination fails. |
Stream maintainable objects from a DDI instance document.
Every element whose tag matches a requested type is yielded, fully
populated, when its end tag is reached. Maintainables nested inside
another requested maintainable are yielded as well and kept in the tree
until the enclosing one is built. Once an element is no longer inside a
requested match it is cleared, so memory is bounded by the largest
outermost match. Request only the types you need, as :func:iter_variables
does, to keep that bound small.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
SourceType
|
The XML content to parse, provided as a path, serialized XML, or file-like object. |
required |
maintainable_types
|
Sequence[type[MaintainableBase]] | None
|
Classes to instantiate when their XML tags are encountered. Defaults to every registered maintainable type. |
None
|
**kwargs
|
object
|
Additional keyword arguments forwarded to
:func: |
{}
|
Yields:
| Type | Description |
|---|---|
MaintainableBase
|
Instances of the requested maintainable classes, innermost first. |
Iterate over :class:Variable maintainables in a DDI instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
SourceType
|
The XML content to parse for |
required |
**kwargs
|
object
|
Additional keyword arguments forwarded to
:func: |
{}
|
Returns:
| Type | Description |
|---|---|
Iterator[Variable]
|
An iterator yielding :class: |
Iterator[Variable]
|
|
Side Effects
Consumes the input stream and prunes processed XML elements via
:func:iterparse_ddi to minimize memory usage.
Iterate over :class:QuestionItem maintainables in a DDI instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
SourceType
|
The XML content to parse for |
required |
**kwargs
|
object
|
Additional keyword arguments forwarded to
:func: |
{}
|
Returns:
| Type | Description |
|---|---|
Iterator[QuestionItem]
|
An iterator yielding :class: |
Iterator[QuestionItem]
|
from |
Side Effects
Consumes the input stream and prunes processed XML elements via
:func:iterparse_ddi to minimize memory usage.
Validation¶
Validate a DDI document and optionally execute lint rules.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
DocumentSource
|
Document payload to validate. |
required |
include_lint
|
bool
|
|
True
|
lint_rules
|
Sequence[str] | None
|
Specific lint rule identifiers to run. |
None
|
lint_profile
|
str | None
|
Named lint profile to execute. |
None
|
raise_error
|
bool
|
|
False
|
include_context
|
bool
|
|
True
|
version
|
str | None
|
DDI schema version to validate against; |
None
|
Validate a fragment instance and return structured issues.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
FragmentSource
|
Fragment payload to validate. |
required |
include_lint
|
bool
|
|
True
|
lint_rules
|
Sequence[str] | None
|
Specific lint rule identifiers to run. |
None
|
lint_profile
|
str | None
|
Named lint profile to execute. |
None
|
raise_error
|
bool
|
|
False
|
include_context
|
bool
|
|
True
|
version
|
str | None
|
DDI schema version to validate against; |
None
|
ValidationReport
dataclass
¶
ValidationReport(
schema_issues: list[SchemaValidationIssue],
lint_findings: list[LintFinding],
)
Aggregate of schema issues and lint findings produced during validation.
iter_messages ¶
iter_messages() -> Iterator[ValidationMessage]
Iterate over unified validation messages.
to_dict ¶
Return a JSON-serialisable representation of the aggregated result.
ValidationMessage
dataclass
¶
ValidationMessage(
message: str,
severity: str,
source: str,
xpath: str | None = None,
context: str | None = None,
location: str | None = None,
rule_id: str | None = None,
)
Normalized representation of validation feedback for UI consumption.
from_lint_finding
classmethod
¶
from_lint_finding(
finding: LintFinding,
) -> ValidationMessage
Build a message from a :class:LintFinding.
from_schema_issue
classmethod
¶
from_schema_issue(
issue: SchemaValidationIssue,
) -> ValidationMessage
Build a message from a :class:SchemaValidationIssue.
Linting¶
Update and return the active :class:LintConfiguration.
Only options explicitly provided are modified. allowed_agencies accepts
None to disable the built-in agency allow-list and any other sequence to
replace it. required_citation_languages expects an iterable of BCP 47
language identifiers that must be present on citation titles.
LintConfiguration
dataclass
¶
LintConfiguration(
allowed_agencies: tuple[str, ...] | None = None,
require_citation: bool = True,
require_citation_title: bool = True,
required_citation_languages: tuple[str, ...] = (),
)
Collection of options governing built-in lint behaviour.
LintFinding
dataclass
¶
Container describing a single lint finding.
as_dict ¶
Return a JSON-serialisable representation of the finding.
Register a linting rule.
target determines whether callback receives the whole
:class:DDIDocument or the root :class:Element of the document.
Exceptions¶
Standardized exception hierarchy for DDI operations.
All DDI-specific exceptions inherit from DDIError and provide rich context including source location, XPath, and original cause.
Exception Hierarchy
DDIError (base) ├── DDIReadError - File/stream reading failures │ └── DDIParseError - Malformed XML or unexpected elements ├── DDIWriteError - Serialization failures ├── DDIValidationError - Schema validation failures ├── DDIModelError - Model constraint violations │ ├── ModelValidationError - Validation check failures │ ├── ModelBuildError - Builder/construction failures │ └── DuplicateIdentifierError - Identifier already in use (ValueError) └── DDIReferenceError - Reference resolution failures (LookupError)
Warning hierarchy
UserWarning └── DDIReferenceWarning - References to items missing from a saved study
ErrorLocation
dataclass
¶
ErrorLocation(
filename: str | None = None,
xpath: str | None = None,
line: int | None = None,
column: int | None = None,
element_tag: str | None = None,
)
Structured details describing where a problem originated.
Attributes:
| Name | Type | Description |
|---|---|---|
filename |
str | None
|
Source file path, if known. |
xpath |
str | None
|
XPath to the problematic element, if applicable. |
line |
int | None
|
Line number in source, if available. |
column |
int | None
|
Column number in source, if available. |
element_tag |
str | None
|
Tag name of the problematic element. |
Example
loc = ErrorLocation( ... filename="study.xml", line=42, ... xpath="/DDIInstance/StudyUnit", ... ) print(loc.describe()) study.xml:42, xpath /DDIInstance/StudyUnit
merge ¶
merge(other: ErrorLocation | None) -> ErrorLocation
Combine this location with another, preferring non-None values.
combine
classmethod
¶
combine(
*locations: ErrorLocation | None,
) -> ErrorLocation | None
Combine multiple locations into one.
from_element
classmethod
¶
from_element(
element: Any, *, xpath: str | None = None
) -> ErrorLocation | None
Create location from an XML element.
from_issue
classmethod
¶
from_issue(
issue: SchemaValidationIssue,
) -> ErrorLocation | None
Create location from a schema validation issue.
DDIError ¶
DDIError(
message: str,
*,
cause: BaseException | None = None,
location: ErrorLocation | None = None,
)
Bases: Exception
Base class for all DDI-specific exceptions.
All DDI exceptions provide: - A human-readable message - Optional location information (file, line, xpath) - Optional original cause for exception chaining
Attributes:
| Name | Type | Description |
|---|---|---|
message |
str
|
The error message without location info. |
location |
Structured location information. |
|
original_exception |
BaseException | None
|
The underlying cause, if any. |
Example
try: ... raise DDIError("Something went wrong", location=ErrorLocation(line=42)) ... except DDIError as e: ... print(e.location.line) 42
original_exception
property
¶
The original exception that triggered this error, if any.
with_location ¶
with_location(location: ErrorLocation) -> DDIError
Return a copy of this exception with updated location.
DDIReadError ¶
DDIReadError(
message: str,
*,
cause: BaseException | None = None,
location: ErrorLocation | None = None,
)
Bases: DDIError
Raised when reading a DDI document fails.
This covers file access errors, encoding issues, and other I/O problems during document loading.
DDIParseError ¶
DDIParseError(
message: str,
*,
cause: BaseException | None = None,
location: ErrorLocation | None = None,
expected_tag: str | None = None,
actual_tag: str | None = None,
element: Any | None = None,
)
Bases: DDIReadError
Raised when XML parsing fails.
This covers syntax errors, malformed XML, and structural issues
encountered during parsing. It is a :class:DDIReadError, so code that
handles read failures also handles malformed input.
Attributes:
| Name | Type | Description |
|---|---|---|
expected_tag |
The tag that was expected, if applicable. |
|
actual_tag |
The tag that was found, if applicable. |
|
element |
The problematic element, if available. |
tag_mismatch
classmethod
¶
tag_mismatch(
expected: str, actual: str, element: Any | None = None
) -> DDIParseError
Create error for tag mismatch.
from_parser_error
classmethod
¶
from_parser_error(
error: BaseException,
*,
sources: Iterable[object] | None = None,
) -> DDIParseError
Wrap an lxml or stdlib parser error, keeping its line and column.
DDIWriteError ¶
DDIWriteError(
message: str,
*,
cause: BaseException | None = None,
location: ErrorLocation | None = None,
)
Bases: DDIError
Raised when writing/serializing a DDI document fails.
This covers file access errors, encoding issues, and serialization problems during document saving.
DDIValidationError ¶
DDIValidationError(
message: str,
*,
issues: Sequence[SchemaValidationIssue] | None = None,
cause: BaseException | None = None,
location: ErrorLocation | None = None,
)
Bases: DDIError
Raised when schema validation fails.
Attributes:
| Name | Type | Description |
|---|---|---|
issues |
list[SchemaValidationIssue]
|
List of individual validation issues found. |
Example
try: ... validate(document) ... except DDIValidationError as e: ... for issue in e.issues: ... print(f"{issue.severity}: {issue.message}")
from_schema_error
classmethod
¶
from_schema_error(
error: BaseException,
*,
sources: Iterable[object] | None = None,
fallback_location: ErrorLocation | None = None,
) -> DDIValidationError
Create from a schema validation error.
DDIModelError ¶
DDIModelError(
message: str,
*,
cause: BaseException | None = None,
location: ErrorLocation | None = None,
)
Bases: DDIError
Base class for model-related errors.
Covers issues with model construction, validation, and constraints.
DuplicateIdentifierError ¶
DuplicateIdentifierError(
message: str,
*,
cause: BaseException | None = None,
location: ErrorLocation | None = None,
)
Bases: DDIModelError, ValueError
Raised when an item is added with an identifier already in the document.
ModelValidationError ¶
ModelValidationError(
message: str,
*,
cause: BaseException | None = None,
location: ErrorLocation | None = None,
model_type: type | None = None,
field_name: str | None = None,
)
Bases: DDIModelError
Raised when a model instance fails validation checks.
This is raised by MaintainableBase.validate() and related methods when required fields are missing or constraints are violated.
Attributes:
| Name | Type | Description |
|---|---|---|
model_type |
The type of model that failed validation. |
|
field_name |
The specific field that caused the failure, if applicable. |
Example
study = StudyUnit(agency=None, identifier="test", version="1.0") study.validate() ModelValidationError: StudyUnit requires agency when URN is not provided.
missing_field
classmethod
¶
missing_field(
model_type: type,
field_name: str,
context: str | None = None,
) -> ModelValidationError
Create error for a missing required field.
invalid_value
classmethod
¶
invalid_value(
model_type: type,
field_name: str,
value: Any,
reason: str | None = None,
) -> ModelValidationError
Create error for an invalid field value.
ModelBuildError ¶
ModelBuildError(
message: str,
*,
cause: BaseException | None = None,
location: ErrorLocation | None = None,
)
Bases: DDIModelError
Raised when model construction via builders fails.
This is raised by builder classes when required configuration is missing or invalid.
DDIReferenceError ¶
DDIReferenceError(
message: str,
*,
cause: BaseException | None = None,
location: ErrorLocation | None = None,
reference_urn: str | None = None,
reference_type: str | None = None,
)
Bases: DDIError, LookupError
Raised when reference resolution fails.
This occurs when a Reference cannot be resolved to its target maintainable within a document.
Attributes:
| Name | Type | Description |
|---|---|---|
reference_urn |
The URN that could not be resolved. |
|
reference_type |
The type of object being referenced. |
unresolved
classmethod
¶
unresolved(
urn: str | None = None,
identifier: str | None = None,
type_of_object: str | None = None,
) -> DDIReferenceError
Create error for an unresolved reference.
DDIReferenceWarning ¶
Bases: UserWarning
Warns that references in a serialized model point at missing items.
One warning is issued per serialization, listing every unresolved
reference, so it can be filtered with warnings.filterwarnings by
category.
Attributes:
| Name | Type | Description |
|---|---|---|
records |
The unresolved references, as
:class: |
location_from_element ¶
location_from_element(
element: object, *, xpath: str | None = None
) -> ErrorLocation | None
Create an ErrorLocation from an XML element.
location_from_source ¶
location_from_source(
source: object,
) -> ErrorLocation | None
Create an ErrorLocation from a source (file path, file object, etc.).
element_xpath ¶
Extract a simple XPath from an element's tag.
build_error_location ¶
build_error_location(
*,
sources: Iterable[object] | None = None,
element: object | None = None,
xpath: str | None = None,
line: int | None = None,
column: int | None = None,
) -> ErrorLocation | None
Build an ErrorLocation from various sources of information.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sources
|
Iterable[object] | None
|
File paths or file objects to extract filename from. |
None
|
element
|
object | None
|
XML element to extract line/column/tag from. |
None
|
xpath
|
str | None
|
Explicit XPath override. |
None
|
line
|
int | None
|
Explicit line number override. |
None
|
column
|
int | None
|
Explicit column number override. |
None
|
Returns:
| Type | Description |
|---|---|
ErrorLocation | None
|
Combined ErrorLocation, or None if no location info available. |