Skip to main content

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.6.0 (breaking): DicomCache's memory tier is now sized by bytes, not entry count — memory_max_entries (default 50) is replaced by memory_max_size_gb (default 1.0).

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.

Metadata

Release files for dimsechord 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dimsechord 0.6.0
File Size Uploaded
dimsechord-0.6.0.tar.gz 100.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dimsechord 0.6.0
File Interpreter ABI Platform
dimsechord-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 145.0 kB

Release files / dimsechord-0.6.0.tar.gz

Download URL dimsechord-0.6.0.tar.gz
Size 100.1 kB
Tags Source
SHA-256 checksum
How to use checksums
8c86c3353e8222e3cb282c3e46a124f4eae55e7201035b06085b9c9bb5d16f93
BLAKE2b-256 checksum
How to use checksums
c80e71e5ec585e18f2c8a407f782bea1e611c6a0be5df490c04eac170578e3b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 14, 2026.

Transparency log

Release files / dimsechord-0.6.0-py3-none-any.whl

Download URL dimsechord-0.6.0-py3-none-any.whl
Size 44.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e705a7faf5fc6a92e51bfd71ad7374ef75cbd01b6045126b1835184969a34b19
BLAKE2b-256 checksum
How to use checksums
ebdf2eac78ab4535645847c890f8bf23422075fdee05502c6bdff7466881475b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 14, 2026.

Transparency log

Release history Release notifications | RSS feed

0.8.0

2 release files

0.7.0

2 release files

This release

0.6.0 This release

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page