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: