Skip to content

Admin Guide

The Admin Guide is intended for system administrators and technical staff responsible for configuring, and maintaining ADIT for DICOM data transfer.

Installation

On the server ADIT lives in a production folder (e.g. adit_prod) that holds the checkout and the .env file:

git clone https://github.com/openradx/adit.git adit_prod
cd adit_prod
uv sync
cp ./example.env ./.env  # set ENVIRONMENT=production and adjust the variables (see below)
uv run cli compose-pull  # pulls the Docker image (ADIT_IMAGE, default ghcr.io/openradx/adit:latest)
uv run cli stack-deploy  # starts the Docker Swarm stack

Environment Variables

All settings are read from .env; the comments in example.env describe every variable. For production at least set:

  • ENVIRONMENT=production
  • Secrets: DJANGO_SECRET_KEY, POSTGRES_PASSWORD, TOKEN_AUTHENTICATION_SALT, SUPERUSER_PASSWORD, SUPERUSER_AUTH_TOKEN (generate with uv run cli generate-django-secret-key, generate-secure-password, generate-auth-token)
  • Hosts: DJANGO_ALLOWED_HOSTS, DJANGO_CSRF_TRUSTED_ORIGINS, SITE_DOMAIN
  • DICOM: CALLING_AE_TITLE, RECEIVER_AE_TITLE (both required), RECEIVER_PORT
  • SSL: SSL_SERVER_CERT_FILE, SSL_SERVER_KEY_FILE, SSL_SERVER_CHAIN_FILE (uv run cli generate-certificate-chain builds the chain from your CA-signed certificate)
  • Email: DJANGO_EMAIL_URL, DJANGO_SERVER_EMAIL, DJANGO_ADMIN_EMAIL, SUPPORT_EMAIL
  • Folders: MOUNT_DIR (download folders, see Folder Management), BACKUP_DIR
  • ANONYMIZATION_SEED for the upload portal

Optional tuning: WEB_REPLICAS, DICOM_WORKER_REPLICAS, MASS_TRANSFER_WORKER_REPLICAS (service scaling), EXCLUDE_MODALITIES (modalities skipped in pseudonymized web transfers, default PR,SR), BACKUP_CRON, DICOM_TASK_STALLED_WORKER_GRACE_SECONDS and DICOM_TASK_SWEEP_CRON (see Worker Crash Recovery), ADIT_IMAGE and STACK_NAME (a second stack such as staging on the same host).

No quotes in .env

Values must not be wrapped in quotes; Docker Swarm treats them as part of the value, and stack-deploy refuses to run when it finds any.

Updating ADIT

  1. Verify no active jobs: Admin Section → Job Overview (/admin-section/) shows nothing pending or in progress
  2. Enable maintenance mode: In Django Admin, Common → Project settings, check "Maintenance" and save
  3. Navigate to the production folder (e.g. adit_prod)
  4. Backup database: uv run cli db-backup
  5. Remove stack: uv run cli stack-rm
  6. Pull latest changes: git pull origin main
  7. Update environment: Compare example.env with your .env and add new or changed variables. Keep STACK_NAME unchanged, otherwise a second stack is deployed next to the old one
  8. Pull Docker images: uv run cli compose-pull
  9. Deploy stack: uv run cli stack-deploy
  10. Disable maintenance mode: Uncheck "Maintenance" in Project settings and save

Worker Crash Recovery

When a worker dies while a task is in progress, the task stays In Progress until a periodic sweep (every minute by default, DICOM_TASK_SWEEP_CRON; also at every worker start) puts it back to Pending once its worker has sent no heartbeat for DICOM_TASK_STALLED_WORKER_GRACE_SECONDS (30 s by default). No manual intervention is needed; a task that stays In Progress much longer than that means the worker is alive but blocked.

User and Group Management

Administrators can create users by navigating to the Django Admin section. Alternatively, users can self-register, after which an administrator must approve and activate their account.

ADIT uses a group-based permission system:

  • Groups define access to specific DICOM servers through source/destination permissions
  • Users are assigned to one or more groups to inherit their permissions

Creating and Managing Groups

  1. Access Django Admin:
  2. Log in as a staff user
  3. Go to Admin Section → Django Admin (available at /django-admin/ URL path)

  4. Create/Edit Groups:

  5. Navigate to Authentication and Authorization → Groups
  6. Click "Add Group" or edit an existing group
  7. Give the group a Name (e.g., "Radiologists", "Research Team")

  8. Assign Permissions:

  9. In the group form, you'll see Available permissions and Chosen permissions
  10. Select the permissions you want from the available list:
    • selective_transfer | selective transfer job | Can process urgently
    • selective_transfer | selective transfer job | Can transfer unpseudonymized
    • batch_transfer | batch transfer job | Can process urgently
    • batch_transfer | batch transfer job | Can transfer unpseudonymized
    • Plus other ADIT-specific permissions for viewing/adding jobs
  11. Move them to Chosen permissions

  12. Add Users to Group:

  13. In the Users section, select users from Available users
  14. Move them to Chosen users
  15. Click Save to apply all changes

Server and Folder Management

Server Management

To add or configure DICOM servers, use the Django Admin interface:

  1. Log in as an administrator
  2. Go to Admin Section → Django Admin (available at /django-admin/ URL path)
  3. Navigate to Core → Dicom servers
  4. Click Add Dicom server
  5. Configure the server details:

Basic Settings: - Name: Friendly name for the server - Ae title: DICOM Application Entity title - Host: Server hostname or IP address - Port: DICOM port number

DICOM Protocol Support: - Patient root find support: Enable C-FIND at patient root level - Patient root get support: Enable C-GET at patient root level - Patient root move support: Enable C-MOVE at patient root level - Study root find support: Enable C-FIND at study root level - Study root get support: Enable C-GET at study root level - Study root move support: Enable C-MOVE at study root level - Store scp support: Enable C-STORE SCP operations

DICOMweb Settings (if applicable): - Dicomweb root url: Base URL for DICOMweb services - Dicomweb qido support: Enable QIDO-RS (queries) - Dicomweb wado support: Enable WADO-RS (retrieval) - Dicomweb stow support: Enable STOW-RS (storage) - Dicomweb qido prefix: URL prefix for QIDO-RS endpoints - Dicomweb wado prefix: URL prefix for WADO-RS endpoints - Dicomweb stow prefix: URL prefix for STOW-RS endpoints - Dicomweb authorization header: Authentication header for DICOMweb requests

Query Settings: - Max search results: Maximum number of C-FIND results per query (default 200). When a search hits this limit, ADIT splits the queried time range into smaller windows and searches again

  1. Configure Group Access: In the DICOM node group accesses section, specify which groups can use this server as source or destination

DICOM Protocol Support

To determine which DICOM protocols are supported by a server, consult the server's DICOM Conformance Statement.

Folder Management

DICOM folders are destinations on a mounted network drive to which users can download data (instead of transferring it to a server). The folder paths must be located below the directory set in MOUNT_DIR, which is mounted as /mnt in the containers.

  1. Access Django Admin: Navigate to Admin Section → Django Admin
  2. Configure Folders: Go to Core → Dicom folders
  3. Add or Edit Folder:
  4. Click Add dicom folder to create a new folder configuration
  5. Enter a Name for the folder (e.g., "Research Downloads")
  6. Specify the Path where DICOM files should be stored
  7. Set the Quota: The disk quota of this folder in GB
  8. Set the Warn size: The used space in GB at which the admins are informed by email
  9. Assign to Groups: In the DICOM node group accesses section, specify which groups can use this folder as destination (a folder is never a source)
  10. Save: Click Save to apply changes

Quota Monitoring

Administrators receive an email when the used space of a folder reaches the configured warn size, allowing proactive storage management.

Job Overview

The Admin Section (available at /admin-section/ for staff users) includes a Job Overview table with one row per job type (Selective Transfer, Batch Query, Batch Transfer, Mass Transfer) and one column per status: Unverified, Pending, In Progress, Canceling, Canceled, Success, Warning, Failure. Each cell shows the number of jobs and links to the filtered job list of all users, where you can open individual jobs for details.

Below the Job Overview, the API Usage table lists per user the time of the last DICOMweb API request, the total response size and the total number of requests.

Broadcasting Messages

Administrators can send an email to all users:

  1. Navigate to Admin Section → Send Email to all users (available at /admin-section/broadcast/)
  2. Enter a subject and the message and send it

System Announcements

System administrators can inform users about important updates, maintenance schedules, or system changes through the announcement feature.

Creating Announcements

  1. Access Admin Interface: Navigate to Admin Section → Django Admin (available at /django-admin/)
  2. Find Project Settings: Go to the "Common" section and select "Project settings"
  3. Edit Announcement: In the Project Settings form, locate the "Announcement" field
  4. Enter Message: Type your announcement message. HTML formatting is supported for rich text display
  5. Save Changes: Click "Save" to publish the announcement

Announcement Display

  • Announcements appear prominently on the main/home page
  • All logged-in users will see the announcement when they access ADIT

Example Announcements

Maintenance Notice:

<strong>Scheduled Maintenance:</strong> ADIT will be offline for maintenance on
<strong>March 15, 2024 from 2:00 AM to 4:00 AM UTC</strong>. Please plan your
transfers accordingly.

ADIT Client

The ADIT Client is a Python library that accesses the DICOMweb API of ADIT. It can query (QIDO-RS), retrieve (WADO-RS, including the NIfTI resources) and store (STOW-RS) DICOM data on the servers the user has access to. It cannot create or manage selective, batch or mass transfer jobs; those are only available in the web interface.

Basic Usage:

from adit_client import AditClient

# Initialize client
client = AditClient(server_url="https://adit.example.com", auth_token="your-api-token")

# Search for studies. The first parameter is the AE title of the DICOM server
# to query, the second a dictionary of DICOM query keys.
studies = client.search_for_studies("ORTHANC1", {"PatientID": "12345"})

# Retrieve all images of a study as pydicom datasets,
# optionally pseudonymized on the fly.
images = client.retrieve_study("ORTHANC1", studies[0].StudyInstanceUID, pseudonym="XFE3TEW2N")

# Store the images on another DICOM server
client.store_images("ORTHANC2", images)

To create an API token for programmatic access:

  1. Navigate to Token Authentication by going to "Profile" --> "Manage API Tokens"
  2. Description & Expiry Time : Add a description (optional) and expiry time for the token.
  3. Click on "Generate Token".
  4. This token will only be visible once, so make sure to copy it now and store it in a safe place. As you will not be able to see it again, you will have to generate a new token if you lose it.

Revoking Tokens

  • Admins can revoke tokens by navigating to Django Admin --> Token Authentication