Skip to main content

Pure-Python building blocks for DICOM and DICOMweb services: DIMSE networking, caching, and DICOM↔JSON conversion.

Project description

dimsechord

Pure-Python toolkit of composable building blocks for DICOM and DICOMweb services.

dimsechord wraps pydicom and pynetdicom behind a small, stable public API. It gives you the networking, caching, and conversion primitives needed to build PACS proxies, DICOMweb gateways, and imaging pipelines — and nothing else: there is no bundled HTTP framework and no opinionated request handlers, so you bring your own web layer.

Features

  • DIMSE SCU — C-FIND, C-STORE, C-MOVE and C-GET, exposed through an async DicomClient.
  • C-STORE SCP — receive incoming instances with StorageSCP, one listener per distinct port; multiple AETs may share a port. All transfer syntaxes are accepted by default, so compressed objects arrive verbatim.
  • AssociationPool — manage multiple AE-Title identities with per-AET concurrency limits.
  • Two-tier cache — in-memory + disk, backed by a SQLite instance index.
  • Streaming pull-engine — move-to-self retrieval streamed instance by instance, with per-UID request coalescing.
  • Streaming query-engine — raw C-FIND pass-through via QueryEngine, streamed response by response under independent per-AET find leases.
  • DICOMweb conversion — DICOM ↔ DICOMweb JSON and multipart/related frame responses.

Runtime dependencies are just pydicom, pynetdicom, and cachetools.

Installation

pip install dimsechord

Requires Python 3.12+.

Quickstart

import asyncio

from dimsechord import (
    AssociationPool, DicomCache, DicomClient, DicomNode, PullEngine,
    SeriesQuery, StorageSCP, StudyQuery, convert_datasets_to_dicom_json,
)

PACS = DicomNode(aet="PACS", host="127.0.0.1", port=11112)


async def main() -> None:
    # 1. Find studies and series (C-FIND, QIDO-style).
    client = DicomClient(calling_aet="MYSCU")
    studies = await client.find_studies(StudyQuery(patient_id="12345"), PACS)
    series = await client.find_series(
        SeriesQuery(study_instance_uid=studies[0].study_instance_uid), PACS)

    # 2. Pull a series move-to-self and build DICOMweb JSON (WADO-style).
    pool = AssociationPool(aets=["MYDEST"])
    scp = StorageSCP()
    scp.start({"MYDEST": 11113})
    # Your PACS must route the AET "MYDEST" back to this SCP's host:port.
    cache = DicomCache(base_dir="./cache", index_path="./cache/index.db")
    engine = PullEngine(pool=pool, scp=scp, cache=cache, pacs=PACS)
    try:
        cached = await engine.ensure_series(
            studies[0].study_instance_uid, series[0].series_instance_uid)
        metadata = convert_datasets_to_dicom_json(
            list(cached.instances.values()), base_url="https://example.org/dicom-web")
        print(len(metadata), "instances")
    finally:
        scp.stop()
        cache.shutdown()


asyncio.run(main())

0.5.1: StorageSCP accepts all transfer syntaxes by default and the new build_storage_scu_contexts() builds forwarding-SCU contexts, so compressed objects pass through verbatim. C-GET now negotiates a curated storage-class set (see CHANGELOG).

0.5.0: the disk cache now records per-series completeness; series cached by earlier versions re-pull once on first read after upgrade (the SQLite schema migrates automatically).

0.4.0 (breaking): StorageSCP.start now takes an {AET: port} mapping (was start(aets, port)), binding one listener per port.

Public API

The supported surface is exactly what dimsechord/__init__.py exports (from dimsechord import …); it is frozen by tests/unit/test_public_api.py.

Everything else lives in underscore-prefixed modules (dimsechord._scu, dimsechord._cache, …) and is private — importing from those modules is unsupported and may break without notice. If you need something that is not exported, extend the public surface rather than reaching into a private module.

Documentation

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dimsechord-0.5.1.tar.gz (98.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dimsechord-0.5.1-py3-none-any.whl (44.4 kB view details)

Uploaded Python 3

File details

Details for the file dimsechord-0.5.1.tar.gz.

File metadata

  • Download URL: dimsechord-0.5.1.tar.gz
  • Upload date:
  • Size: 98.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dimsechord-0.5.1.tar.gz
Algorithm Hash digest
SHA256 7fda95c8c5aad7e7db1b3c0e7e99fe9ba739c21618f083989342a85f1b3bac8b
MD5 dc72583d38d9a385c7fd2a7315032bf7
BLAKE2b-256 0abc0420d7624903f64760a7036143d0b98fd29fe77e9202e6d7d614d76c108c

See more details on using hashes here.

Provenance

The following attestation bundles were made for dimsechord-0.5.1.tar.gz:

Publisher: release.yml on radionest/dimsechord

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dimsechord-0.5.1-py3-none-any.whl.

File metadata

  • Download URL: dimsechord-0.5.1-py3-none-any.whl
  • Upload date:
  • Size: 44.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dimsechord-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 aa3d1618f3a663abab38c80df051d8f7ff40f92cd130e8aec37922d0035a9612
MD5 1c40bbe60519bac1a8e3f1139349ec2d
BLAKE2b-256 b7688a9a8ffa111db44520f9cb31f5304c6d3fb89f6f7355149dc68068a7ad2e

See more details on using hashes here.

Provenance

The following attestation bundles were made for dimsechord-0.5.1-py3-none-any.whl:

Publisher: release.yml on radionest/dimsechord

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page