Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 110 additions & 2 deletions orthanc/python/orthanc_graphql.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,46 @@
"""
import json

from ariadne import QueryType, graphql_sync, make_executable_schema
from ariadne import ObjectType, QueryType, graphql_sync, make_executable_schema

import orthanc

# 1. Define a GraphQL schema mirroring DICOM tags
TYPE_DEFS = """
type Instance {
id: ID!
sopInstanceUID: String!
instanceNumber: String
}

type Series {
id: ID!
seriesInstanceUID: String!
modality: String!
seriesDescription: String
seriesNumber: String
manufacturer: String
instances(limit: Int = 100): [Instance!]!
}

type Study {
id: ID!
studyInstanceUID: String!
studyDate: String
studyTime: String
accessionNumber: String
referringPhysicianName: String
studyDescription: String
series(limit: Int = 100): [Series!]!
}

type Patient {
id: ID!
patientId: String!
patientName: String!
patientBirthDate: String
patientSex: String
studies(limit: Int = 100): [Study!]!
}

type Query {
Expand All @@ -24,6 +52,9 @@
"""

query = QueryType()
patient_type = ObjectType("Patient")
study_type = ObjectType("Study")
series_type = ObjectType("Series")


@query.field("patients")
Expand All @@ -50,7 +81,84 @@ def resolve_patients(_, _info, limit=100, since=0):
return results


schema = make_executable_schema(TYPE_DEFS, query)
@patient_type.field("studies")
def resolve_patient_studies(patient_obj, _info, limit=100):
"""Resolver bringing nested Studies for a given Patient."""
# We must fetch the given patient ID's studies
patient_id = patient_obj['id']
# If the user queries > 100 limit, make sure to respect it, but limit is standard at 100
response = orthanc.RestApiGet(f'/patients/{patient_id}')
patient_details = json.loads(response)

study_ids = patient_details.get("Studies", [])[:limit]

results = []
for study_id in study_ids:
# expand the study details using RestApiGet
s_resp = orthanc.RestApiGet(f'/studies/{study_id}')
s = json.loads(s_resp)
tags = s.get('MainDicomTags', {})
results.append({
'id': s.get('ID', ''),
'studyInstanceUID': tags.get('StudyInstanceUID', ''),
'studyDate': tags.get('StudyDate'),
'studyTime': tags.get('StudyTime'),
'accessionNumber': tags.get('AccessionNumber'),
'referringPhysicianName': tags.get('ReferringPhysicianName'),
'studyDescription': tags.get('StudyDescription')
})
return results


@study_type.field("series")
def resolve_study_series(study_obj, _info, limit=100):
"""Resolver bringing nested Series for a given Study."""
study_id = study_obj['id']
response = orthanc.RestApiGet(f'/studies/{study_id}')
study_details = json.loads(response)

series_ids = study_details.get("Series", [])[:limit]

results = []
for series_id in series_ids:
s_resp = orthanc.RestApiGet(f'/series/{series_id}')
s = json.loads(s_resp)
tags = s.get('MainDicomTags', {})
results.append({
'id': s.get('ID', ''),
'seriesInstanceUID': tags.get('SeriesInstanceUID', ''),
'modality': tags.get('Modality', ''),
'seriesDescription': tags.get('SeriesDescription'),
'seriesNumber': tags.get('SeriesNumber'),
'manufacturer': tags.get('Manufacturer')
})
return results


@series_type.field("instances")
def resolve_series_instances(series_obj, _info, limit=100):
"""Resolver bringing nested Instances for a given Series."""
series_id = series_obj['id']
response = orthanc.RestApiGet(f'/series/{series_id}')
series_details = json.loads(response)

instance_ids = series_details.get("Instances", [])[:limit]

results = []
for instance_id in instance_ids:
i_resp = orthanc.RestApiGet(f'/instances/{instance_id}')
i = json.loads(i_resp)
tags = i.get('MainDicomTags', {})
results.append({
'id': i.get('ID', ''),
'sopInstanceUID': tags.get('SOPInstanceUID', ''),
'instanceNumber': tags.get('InstanceNumber')
})
return results


schema = make_executable_schema(TYPE_DEFS, query, patient_type, study_type,
series_type)


def graphql_endpoint(output, _url, **request):
Expand Down
Loading