Getting Started with odmlib
odmlib is a Python library for working with CDISC ODM (Operational Data Model) documents and its extensions. It provides an object-oriented interface for creating, parsing, and validating ODM files with XML and JSON serialization.
Installation
Install from PyPI:
pip install odmlib
For development (editable install with all dev tools):
git clone https://github.com/swhume/odmlib.git
cd odmlib
pip install -e ".[dev]"
Supported Standards
Standard |
Package |
Status |
|---|---|---|
ODM 1.3.2 |
|
Stable |
ODM 2.0 |
|
Draft |
Define-XML 2.0 |
|
Stable |
Define-XML 2.1 |
|
Stable |
Dataset-XML 1.0.1 |
|
Stable |
CT-XML 1.1.1 |
|
Stable |
ARM 1.0 |
|
Stable |
Dataset-JSON 1.1 |
|
Stable |
Quick Start
Loading an ODM-XML File
import odmlib.odm_loader as OL
import odmlib.loader as LD
# Create a loader for ODM 1.3.2 XML
loader = LD.ODMLoader(OL.XMLODMLoader(model_package="odm_1_3_2"))
loader.open_odm_document("my_study.xml")
# Get the root ODM object
odm = loader.root()
print(f"File OID: {odm.FileOID}")
# Get the first MetaDataVersion
mdv = loader.MetaDataVersion()
# List all item groups (datasets/domains)
for igd in mdv.ItemGroupDef:
print(f" {igd.OID}: {igd.Name}")
Creating an ODM Document from Scratch
import odmlib.odm_1_3_2.model as ODM
import odmlib.ns_registry as NS
# Set up the namespace registry
NS.NamespaceRegistry(prefix="odm",
uri="http://www.cdisc.org/ns/odm/v1.3",
is_default=True, is_reset=True)
# Build the study name and global variables
sn = ODM.StudyName(_content="My Clinical Study")
sd = ODM.StudyDescription(_content="A phase II clinical trial")
pn = ODM.ProtocolName(_content="STUDY-001")
gv = ODM.GlobalVariables(StudyName=sn, StudyDescription=sd, ProtocolName=pn)
# Create an item definition
item = ODM.ItemDef(OID="IT.AGE", Name="Age", DataType="integer", Length=3)
# Create an item group definition
igd = ODM.ItemGroupDef(OID="IG.DM", Name="Demographics", Repeating="No")
igd.ItemRef.append(ODM.ItemRef(ItemOID="IT.AGE", Mandatory="Yes", OrderNumber=1))
# Assemble the metadata version
mdv = ODM.MetaDataVersion(OID="MDV.001", Name="Version 1")
mdv.ItemGroupDef.append(igd)
mdv.ItemDef.append(item)
# Create the study and ODM root
study = ODM.Study(OID="S.001", GlobalVariables=gv, MetaDataVersion=[mdv])
odm = ODM.ODM(
FileOID="F.001",
FileType="Snapshot",
CreationDateTime="2024-01-01T00:00:00",
Study=[study]
)
# Write to XML
odm.write_xml("my_study.xml")
Key Concepts
Bottom-up construction: ODM objects are built from leaves to root. Create child elements first, then pass them to parent constructors.
Descriptor validation: All attribute assignments are validated at
assignment time. Invalid values raise
OdmlibTypeError or
OdmlibValidationError.
Namespace management: Use NamespaceRegistry
to register XML namespaces before creating or loading documents. Call
reset() to clear namespace state between
independent operations.
Bidirectional serialization: All elements support
to_xml_string(),
to_element(),
to_json(), and
to_dict() for conversion back to
standard formats.
Next Steps
Reading ODM Documents – Load and navigate existing ODM documents
Creating ODM Documents – Build ODM documents from scratch
Validating ODM Documents – Validate ODM documents
Model Reference – Understand the supported models and standards