Install & Compatibility
Where this runs
tested against v3.0.4 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.940 runs
installs and imports cleanly · install 0.0s · import 0.941s · 47MB
glibcpy 3.10–3.940 runs
installs and imports cleanly · install 2.8s · import 0.895s · 48MB
41MB installed
● package 41MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
AE
✓ from pynetdicom import AE
✗ from pynetdicom.apps import AE
In v3.0+, AE is directly in the top-level package, not in 'apps'.
evt
✓ from pynetdicom import evt
✗ ae._handle_association_release
Event handlers in v3.0+ use `evt` constants and `AE.register_event_handler` instead of directly overriding internal AE methods.
VerificationPresentationContexts
✓ from pynetdicom.presentation import VerificationPresentationContexts
✗ from pynetdicom.sop_class import VerificationSOPClass
While `VerificationSOPClass` exists, `VerificationPresentationContexts` provides a pre-configured list of contexts ready for use.
StoragePresentationContexts
✓ from pynetdicom.presentation import StoragePresentationContexts
Used for pre-configured presentation contexts for common storage SOP classes.
This quickstart demonstrates how to create a simple DICOM Service Class User (SCU) that establishes an association with a remote DICOM Service Class Provider (SCP) and sends a C-ECHO request (a DICOM 'ping'). It uses environment variables for configuration, making it runnable without modification.
from pynetdicom import AE, VerificationPresentationContexts
import logging
import os
# Configure logging to see association details (optional but recommended)
logging.basicConfig(level=logging.INFO)
# Initialise the Application Entity (AE) for the SCU
# AE Titles must be bytes objects (e.g., b'MY_AE_TITLE')
scu_ae_title = os.environ.get('PYNETDICOM_AE_TITLE_SCU', 'PYNETDICOM_SCU').encode('utf-8')
ae = AE(ae_title=scu_ae_title)
# Add a supported presentation context for the Verification SOP Class (C-ECHO)
# This tells the AE what services it can request/provide.
ae.add_supported_context(VerificationPresentationContexts[0])
# Define the target SCP's details (can be read from environment variables for flexibility)
target_ip = os.environ.get('PYNETDICOM_TARGET_IP', '127.0.0.1')
target_port = int(os.environ.get('PYNETDICOM_TARGET_PORT', '11112'))
target_ae_title = os.environ.get('PYNETDICOM_TARGET_AE_TITLE', 'ANY_SCP_AE').encode('utf-8')
print(f"\nAttempting to associate {scu_ae_title.decode()} with {target_ae_title.decode()} at {target_ip}:{target_port}...")
print("NOTE: Ensure a DICOM SCP is running at this address and listening on the specified port.")
# Attempt to establish an association with the remote AE (SCP)
assoc = ae.associate(target_ip, target_port, ae_title=target_ae_title)
if assoc.is_established:
print('\nAssociation established with peer.')
# Send a C-ECHO request to verify connection
status = assoc.send_c_echo()
print(f'C-ECHO response status: {status}')
# Release the association gracefully
assoc.release()
print('Association released.')
else:
print('\nAssociation rejected, aborted or never connected.')
# Clean up any resources (e.g., server threads) associated with the AE
ae.shutdown()
Errors
Common errors & fixes
Association Rejected (0x01)
The remote AE rejected the association. Common reasons include unsupported presentation contexts, incorrect AE titles, or security issues (e.g., TLS mismatch).
fixCheck that your `ae.add_supported_context()` calls match what the remote AE supports. Ensure AE titles are correct and formatted as `bytes`. Verify TLS/SSL settings if applicable. Check the SCP's logs for a more specific reason for rejection.
TypeError: a bytes-like object is required, not 'str'
An AE title (either for the local AE or the remote AE in `ae.associate`) was provided as a Python string instead of a `bytes` object.
fixEncode your AE titles to bytes: `AE(ae_title=b'MY_AE_TITLE')` or `ae.associate(..., ae_title=my_string.encode('utf-8'))`. ValueError: No Presentation Context for Verification SOP Class
You attempted to send a C-ECHO (or similar service) without having an accepted presentation context for the corresponding SOP Class.
fixBefore associating, add the required presentation context: `ae.add_supported_context(VerificationPresentationContexts[0])` for C-ECHO, or similar for other services.
RuntimeWarning: You have not called ae.shutdown(). This can lead to uncleaned resources and your program hanging.
The `AE` object was garbage collected or the program exited without explicitly calling its `shutdown()` method, leaving internal threads or resources open.
fixAlways call `ae.shutdown()` when your `AE` instance is no longer needed, typically at the end of your script or within a `finally` block.
Upgrade
Version history
3.0.4latest on PyPI · released Aug 2, 2025
Audit
Dependencies
pydicomrequiredRequired for working with actual DICOM datasets (e.g., sending/receiving images). While not a strict runtime dependency for the network protocol itself, almost all practical applications of pynetdicom will need it.
cryptographyoptionalRequired for secure communication using TLS/SSL (dicomweb-tls).
numpyoptionalRecommended for efficient handling of pixel data arrays within DICOM datasets.