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.
- DICOMweb conversion — DICOM ↔ DICOMweb JSON and
multipart/relatedframe 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.4.0 (breaking):
StorageSCP.startnow takes an{AET: port}mapping (wasstart(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
- Why dimsechord — what problems it solves.
- Typing — how the typed API works with mypy/pyright.
- Cookbook — one recipe per feature.
- Gateway tutorial — an end-to-end DICOMweb gateway.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dimsechord-0.4.0.tar.gz.
File metadata
- Download URL: dimsechord-0.4.0.tar.gz
- Upload date:
- Size: 70.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1fdaeed5a5a08a14a0a61922faa35d85c8eadb574c9bfbfcd79b38344e24c9a
|
|
| MD5 |
80528c86abca7de2f0e4e88561736544
|
|
| BLAKE2b-256 |
7244bc7cb9bb31c21b55e6f941ee278959a6cd31d28d7724b58fd8c215f82870
|
Provenance
The following attestation bundles were made for dimsechord-0.4.0.tar.gz:
Publisher:
release.yml on radionest/dimsechord
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dimsechord-0.4.0.tar.gz -
Subject digest:
d1fdaeed5a5a08a14a0a61922faa35d85c8eadb574c9bfbfcd79b38344e24c9a - Sigstore transparency entry: 2008308427
- Sigstore integration time:
-
Permalink:
radionest/dimsechord@5ea7b781bc7c20dbd63811ec24f88a2491ef3cb2 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/radionest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5ea7b781bc7c20dbd63811ec24f88a2491ef3cb2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dimsechord-0.4.0-py3-none-any.whl.
File metadata
- Download URL: dimsechord-0.4.0-py3-none-any.whl
- Upload date:
- Size: 33.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0692f4b7976f0d9c079136fd12621e4b2dc1aa260b68bb879422aa3b9e139859
|
|
| MD5 |
5b5f68388ce7bc91105f3b23e57a6f2d
|
|
| BLAKE2b-256 |
3a6dccfa209f618094f487d3f77dbb2683b61360dd0c9f377a56f2e5cb91563e
|
Provenance
The following attestation bundles were made for dimsechord-0.4.0-py3-none-any.whl:
Publisher:
release.yml on radionest/dimsechord
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dimsechord-0.4.0-py3-none-any.whl -
Subject digest:
0692f4b7976f0d9c079136fd12621e4b2dc1aa260b68bb879422aa3b9e139859 - Sigstore transparency entry: 2008308621
- Sigstore integration time:
-
Permalink:
radionest/dimsechord@5ea7b781bc7c20dbd63811ec24f88a2491ef3cb2 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/radionest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5ea7b781bc7c20dbd63811ec24f88a2491ef3cb2 -
Trigger Event:
push
-
Statement type: