Models API

The models package provides Pydantic data models for XNAT resources with validation, serialization, and table formatting capabilities.

Base Models

Foundation classes that all resource models inherit from.

Model Hierarchy:

PydanticBaseModel
└── BaseModel
    └── XNATResource
        ├── Project
        ├── Subject
        ├── Session (Experiment)
        ├── Scan
        └── Resource

Common Features:

All models provide:

  • Automatic validation of field types and constraints

  • JSON serialization/deserialization

  • Table row formatting for Rich output

  • Alias support for XNAT API field names (e.g., IDid)

  • Nullable field handling with None defaults

BaseModel

Common configuration and utility methods for all models.

class xnatctl.models.base.BaseModel[source]

Bases: BaseModel

Base model with common configuration.

model_config = {'extra': 'ignore', 'populate_by_name': True, 'str_strip_whitespace': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

to_dict()[source]

Convert model to dictionary.

to_row(columns)[source]

Convert model to row dict for table output.

XNATResource

Base class for all XNAT resource types with common fields.

class xnatctl.models.base.XNATResource(*, ID, label=None, URI=None, xsiType=None, insert_date=None, insert_user=None)[source]

Bases: BaseModel

Base model for XNAT resources with common fields.

id: str
label: str | None
uri: str | None
xsi_type: str | None
insert_date: datetime | None
insert_user: str | None
property display_id: str

Return label if available, otherwise ID.

model_config = {'extra': 'ignore', 'populate_by_name': True, 'str_strip_whitespace': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

Project

Represents an XNAT project containing subjects and sessions.

Model Structure:

A project is the top-level organizational unit in XNAT. It contains subjects (participants) and sessions (imaging visits).

Usage Example:

from xnatctl.core.client import XNATClient
from xnatctl.services.projects import ProjectService

client = XNATClient(base_url="https://xnat.example.org")
client.authenticate()

service = ProjectService(client)
projects = service.list()

for project in projects:
    print(f"{project.id}: {project.name}")
    print(f"  PI: {project.pi}")
    print(f"  Subjects: {project.subject_count}")
    print(f"  Sessions: {project.session_count}")
class xnatctl.models.project.Project(*, ID, label=None, URI=None, xsiType=None, insert_date=None, insert_user=None, name=None, secondary_ID=None, description=None, pi_firstname=None, pi_lastname=None, accessibility=None, subjects=None, experiments=None)[source]

Bases: XNATResource

XNAT project resource.

name: str | None
secondary_id: str | None
description: str | None
pi_firstname: str | None
pi_lastname: str | None
accessibility: str | None
subject_count: int | None
session_count: int | None
property pi: str

Return formatted PI name.

classmethod table_columns()[source]

Return columns for table output.

to_row(columns=None)[source]

Convert to row for table output.

model_config = {'extra': 'ignore', 'populate_by_name': True, 'str_strip_whitespace': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

Subject

Represents a subject (participant/patient) within a project.

Model Structure:

Subjects belong to a single project and can have multiple imaging sessions.

class xnatctl.models.subject.Subject(*, ID, label=None, URI=None, xsiType=None, insert_date=None, insert_user=None, project=None, group=None, src=None, gender=None, handedness=None, yob=None, dob=None, education=None, ses=None, race=None, ethnicity=None, experiments=None)[source]

Bases: XNATResource

XNAT subject resource.

project: str | None
group: str | None
src: str | None
gender: str | None
handedness: str | None
yob: int | None
dob: str | None
education: str | None
ses: str | None
race: str | None
ethnicity: str | None
session_count: int | None
classmethod table_columns()[source]

Return columns for table output.

to_row(columns=None)[source]

Convert to row for table output.

model_config = {'extra': 'ignore', 'populate_by_name': True, 'str_strip_whitespace': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

Session (Experiment)

Represents an imaging session or experiment. A session contains scans and resources.

Model Structure:

Sessions are the primary data collection events in XNAT. They belong to a subject and contain one or more scans (individual imaging series).

Modality Types:

Common modality values:

  • MR - Magnetic Resonance Imaging

  • PET - Positron Emission Tomography

  • CT - Computed Tomography

  • US - Ultrasound

  • XA - X-Ray Angiography

Usage Example:

from xnatctl.services.sessions import SessionService

service = SessionService(client)
sessions = service.list(project="MYPROJECT", modality="MR")

for session in sessions:
    print(f"{session.label} - {session.session_date}")
    print(f"  Subject: {session.subject_label}")
    print(f"  Scans: {session.scan_count}")
    print(f"  Modality: {session.modality}")
class xnatctl.models.session.Session(*, ID, label=None, URI=None, xsiType=None, insert_date=None, insert_user=None, project=None, subject_ID=None, subject_label=None, modality=None, session_type=None, acquisition_site=None, scanner=None, operator=None, dcmAccessionNumber=None, dcmPatientId=None, dcmPatientName=None, date=None, time=None, age=None, scans=None, resources=None, note=None, visit_id=None)[source]

Bases: XNATResource

XNAT session/experiment resource.

project: str | None
subject_id: str | None
subject_label: str | None
modality: str | None
session_type: str | None
acquisition_site: str | None
scanner: str | None
operator: str | None
dcm_accession_number: str | None
dcm_patient_id: str | None
dcm_patient_name: str | None
session_date: date | None
time: str | None
age: int | None
scan_count: int | None
resource_count: int | None
note: str | None
visit_id: str | None
classmethod table_columns()[source]

Return columns for table output.

to_row(columns=None)[source]

Convert to row for table output.

model_config = {'extra': 'ignore', 'populate_by_name': True, 'str_strip_whitespace': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

Scan

Represents an individual imaging scan (series) within a session.

Model Structure:

Scans are the lowest-level imaging data unit in XNAT. Each scan represents a single imaging series (e.g., T1-weighted MRI, PET acquisition).

class xnatctl.models.scan.Scan(*, ID, label=None, URI=None, xsiType=None, insert_date=None, insert_user=None, type=None, series_description=None, quality=None, condition=None, note=None, frames=None, startTime=None, scanner=None, modality=None, file_count=None, file_size=None, session_id=None, project=None)[source]

Bases: XNATResource

XNAT scan resource.

type: str | None
series_description: str | None
quality: str | None
condition: str | None
note: str | None
frames: int | None
start_time: str | None
scanner: str | None
modality: str | None
file_count: int | None
file_size: int | None
session_id: str | None
project: str | None
classmethod table_columns()[source]

Return columns for table output.

to_row(columns=None)[source]

Convert to row for table output.

property file_size_mb: float

Return file size in megabytes.

model_config = {'extra': 'ignore', 'populate_by_name': True, 'str_strip_whitespace': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

Resource

Represents a file resource attached to a project, subject, session, or scan.

Model Structure:

Resources are file containers (like folders) that can be attached to any XNAT resource. Common resource types include DICOM, NIFTI, SNAPSHOTS.

Usage Example:

from xnatctl.services.resources import ResourceService

service = ResourceService(client)
resources = service.list(
    project="MYPROJECT",
    session="SESSION01"
)

for resource in resources:
    print(f"{resource.label} - {resource.file_count} files")
    print(f"  Size: {resource.size_bytes} bytes")
    print(f"  Format: {resource.format}")
class xnatctl.models.resource.Resource(*, ID, label=None, URI=None, xsiType=None, insert_date=None, insert_user=None, format=None, content=None, file_count=None, file_size=None, category=None, cacheable=None, session_id=None, scan_id=None, project=None)[source]

Bases: XNATResource

XNAT resource (file collection).

format: str | None
content: str | None
file_count: int | None
file_size: int | None
category: str | None
cacheable: bool | None
session_id: str | None
scan_id: str | None
project: str | None
classmethod table_columns()[source]

Return columns for table output.

to_row(columns=None)[source]

Convert to row for table output.

property file_size_mb: float

Return file size in megabytes.

property file_size_display: str

Return human-readable file size.

model_config = {'extra': 'ignore', 'populate_by_name': True, 'str_strip_whitespace': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

Progress Models

Data models for tracking upload and download progress.

Progress models for tracking operation status.

Provides dataclasses for upload/download progress and operation summaries.

class xnatctl.models.progress.OperationPhase(*values)[source]

Operation phases for progress tracking.

PREPARING = 'preparing'
ARCHIVING = 'archiving'
UPLOADING = 'uploading'
DOWNLOADING = 'downloading'
PROCESSING = 'processing'
COMPLETE = 'complete'
ERROR = 'error'
class xnatctl.models.progress.Progress(phase, current=0, total=0, message='', success=True, errors=<factory>)[source]

Base progress information.

phase: OperationPhase
current: int = 0
total: int = 0
message: str = ''
success: bool = True
errors: list[str]
property percent: float

Calculate completion percentage.

property is_complete: bool

Check if operation is complete.

property has_errors: bool

Check if operation has errors.

class xnatctl.models.progress.UploadProgress(phase, current=0, total=0, message='', success=True, errors=<factory>, batch_id=0, bytes_sent=0, total_bytes=0, file_path='')[source]

Upload-specific progress.

batch_id: int = 0
bytes_sent: int = 0
total_bytes: int = 0
file_path: str = ''
property bytes_percent: float

Calculate bytes completion percentage.

property mb_sent: float

Return megabytes sent.

property total_mb: float

Return total megabytes.

class xnatctl.models.progress.DownloadProgress(phase, current=0, total=0, message='', success=True, errors=<factory>, bytes_received=0, total_bytes=0, file_path='', file_name='')[source]

Download-specific progress.

bytes_received: int = 0
total_bytes: int = 0
file_path: str = ''
file_name: str = ''
property bytes_percent: float

Calculate bytes completion percentage.

property mb_received: float

Return megabytes received.

property total_mb: float

Return total megabytes.

class xnatctl.models.progress.OperationResult(success, total, succeeded, failed, duration, errors=<factory>)[source]

Generic operation result.

success: bool
total: int
succeeded: int
failed: int
duration: float
errors: list[str]
property success_rate: float

Calculate success rate percentage.

class xnatctl.models.progress.UploadSummary(success, total, succeeded, failed, duration, errors=<factory>, total_files=0, total_size_mb=0.0, batches_total=0, batches_succeeded=0, batches_failed=0, session_id='', upload_id='')[source]

Upload operation summary.

total_files: int = 0
total_size_mb: float = 0.0
batches_total: int = 0
batches_succeeded: int = 0
batches_failed: int = 0
session_id: str = ''
upload_id: str = ''
property throughput_mbps: float

Calculate upload throughput in MB/s.

class xnatctl.models.progress.DownloadSummary(success, total, succeeded, failed, duration, errors=<factory>, total_files=0, total_size_mb=0.0, output_path='', session_id='', verified=False)[source]

Download operation summary.

total_files: int = 0
total_size_mb: float = 0.0
output_path: str = ''
session_id: str = ''
verified: bool = False
property throughput_mbps: float

Calculate download throughput in MB/s.