Query by UserMetadata?

Hello! I want to flag studies that Orthanc was unable to POST to a certain endpoint. To do so, I defined a metadata variable like this:

“UserMetadata” : {
“Pending” : 14500
}

Now I would like to query studies containing a certain value inside the Pending metadata variable. Is that possible?

Hi Diego,

No, there’s no way to do that. In your case, I would advise to store the IDs of these failing studies in an external DB or message queue.

HTH,

Alain

Hello Alain! In fact, I couldn’t use UserMetadata for this. The original idea was to create a routine to check for pending studies. I changed the idea a bit and now I implemented an in-memory storage of failed studies inside Orthanc. It works like this:

First I define an attribute (the in-memory “storage”):

pendingStudies = {}

In the NEW_STUDY event, I try to POST the study to another system. If it fails, I save the study into the in-memory storage:

def onNewStudy(resourceId):
study = json.loads(orthanc.RestApiGet(‘/studies/%s’ % resourceId))
body = {
**study,
‘origin’: ‘###ORIGIN###’
}

try:
response = httpClient.post(url=“###SISMED_FULL_URL###/api/dicom-exams”, json = body, auth = HTTPBasicAuth(‘###SISMED_ADMIN###’, ‘###SISMED_ADMIN_PASSWORD###’), verify = False)

if response.ok:
orthanc.LogWarning(f"CRIADO: {resourceId}“)
else:
pendingStudies[resourceId] = body
orthanc.LogError(f"ERRO NA CRIAÇÃO DO EXAME NO SISMED. GUARDADO NA LISTA DE PENDÊNCIAS: {resourceId}”)
except requests.exceptions.RequestException as ex:
pendingStudies[resourceId] = body
orthanc.LogError(f"ERRO NA CRIAÇÃO DO EXAME NO SISMED. GUARDADO NA LISTA DE PENDÊNCIAS: {resourceId}“)
orthanc.LogError(f”{ex}")

Then in the ORTHANC_STARTED event I spawn a helper thread that checks every 10 minutes the in-memory storage for pending studies:

def OnChange(changeType, level, resourceId):
if changeType == orthanc.ChangeType.ORTHANC_STARTED:
startThreads()

def startThreads():
producerThread = threading.Thread(None, onFailedStudies, None)
producerThread.daemon = True
producerThread.start()

def onFailedStudies():
while True:
time.sleep(600)
finishedStudies = []

for key in pendingStudies:
study = pendingStudies[key]
orthanc.LogWarning(f"Reprocessando exame não recebido no Sismed: {key}")

try:
response = httpClient.post(url=“###SISMED_FULL_URL###/api/dicom-exams”, json = study, auth = HTTPBasicAuth(‘###SISMED_ADMIN###’, ‘###SISMED_ADMIN_PASSWORD###’), verify = False)

if response.ok:
finishedStudies.append(key)

try:
isStable = bool(orthanc.RestApiGet(f"/studies/{key}/metadata/Stable").decode())
statistics = json.loads(orthanc.RestApiGet(f"/studies/{key}/statistics"))
series = json.loads(orthanc.RestApiGet(f"/studies/{key}/series"))
study.get(‘MainDicomTags’)[‘stationName’] = ‘,’.join(filter(None, set(map(lambda s: s.get(‘MainDicomTags’).get(‘StationName’), series))))
study.get(‘MainDicomTags’)[‘modalities’] = ‘,’.join(filter(None, set(map(lambda s: s.get(‘MainDicomTags’).get(‘Modality’), series))))
study.get(‘MainDicomTags’)[‘manufacturers’] = ‘,’.join(filter(None, set(map(lambda s: s.get(‘MainDicomTags’).get(‘Manufacturer’), series))))
study.get(‘MainDicomTags’)[‘bodyPartsExamined’] = ‘,’.join(filter(None, set(map(lambda s: s.get(‘MainDicomTags’).get(‘BodyPartExamined’), series))))
body = {
**study,
**statistics
}

response = httpClient.put(url = f"###SISMED_FULL_URL###/api/dicom-exams/stable/{key}", json = body, auth = HTTPBasicAuth(‘###SISMED_ADMIN###’, ‘###SISMED_ADMIN_PASSWORD###’), verify = False)

if response.ok:
orthanc.LogWarning(f"EXAME RECEBIDO E ESTABILIZADO NO SISMED. ESTÁVEL: {key}“)
except orthanc.OrthancException as ex:
orthanc.LogWarning(f"EXAME RECEBIDO NO SISMED: {key}”)
else:
orthanc.LogError(f"ERRO NA NOVA TENTATIVA DE CRIAÇÃO DO EXAME NO SISMED. MANTIDO NA LISTA DE PENDÊNCIAS: {key}“)
except requests.exceptions.RequestException as ex:
orthanc.LogError(f"ERRO NA NOVA TENTATIVA DE CRIAÇÃO DO EXAME NO SISMED. MANTIDO NA LISTA DE PENDÊNCIAS: {key}”)

for key in finishedStudies:
pendingStudies.pop(key)

I just needed some additional logic to handle possibly stabilized pending studies.

A quinta-feira, 28 de abril de 2022 à(s) 06:47:21 UTC+1, a…@orthanc.team escreveu: