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.
  • 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.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.0.tar.gz (90.9 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.0-py3-none-any.whl (41.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: dimsechord-0.5.0.tar.gz
  • Upload date:
  • Size: 90.9 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.0.tar.gz
Algorithm Hash digest
SHA256 b9dd68840dfef020570989b657e8440a9f3dbf59f47cde2d82574298c4a83e7d
MD5 9148e66a4859c61bdf9ce39d563bc91e
BLAKE2b-256 aa92be5277b44f28d2241385e7c1fd28d76092f514957c3ca807d5d6e5ffaf71

See more details on using hashes here.

Provenance

The following attestation bundles were made for dimsechord-0.5.0.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.0-py3-none-any.whl.

File metadata

  • Download URL: dimsechord-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 41.0 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 34fb2cd3a1d08c25c7477cbfac9c29563f451348eba496cecfeb98bf15d9cd9b
MD5 c0374cf60c68e50cb25d89fb100b2c5d
BLAKE2b-256 851279fc414c2cee1a893085ed7a52a6681a7e5e069ad651039ab47a8020c7aa

See more details on using hashes here.

Provenance

The following attestation bundles were made for dimsechord-0.5.0-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