Skip to content

650 anonymisation reads from queue - #663

Open
ruaridhg wants to merge 45 commits into
mainfrom
650-anonymisation-reads-from-queue
Open

ruaridhg wants to merge 45 commits into
mainfrom
650-anonymisation-reads-from-queue

Conversation

@ruaridhg

@ruaridhg ruaridhg commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes PIX-68

Fixes #650: Adds new queue "anonymisation" in pixl_core/anon_queue without async functionality, within orthanc adds anon_queue (to replace POST call which hasn't been removed yet), adds "anonymisation" to queue_to_count within the cli and adds corresponding tests within cli and pixl_core.

Type of change

Please delete options accordingly to the description.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Suggested Checklist

  • I have performed a self-review of my own code.
  • I have made corresponding changes to the documentation.
  • My changes generate no new warnings.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have passed on my local host device. (see further details at the CONTRIBUTING document)
  • Make sure your branch is up-to-date with main branch. See CONTRIBUTING for a general example to syncronise your branch with the main branch.
  • I have requested review to this PR.
  • I have addressed and marked as resolved all the review comments in my PR.
  • Finally, I have selected squash and merge

@ruaridhg ruaridhg linked an issue Aug 21, 2026 that may be closed by this pull request
3 tasks
@codecov

codecov Bot commented Aug 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.10145% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.32%. Comparing base (e69648d) to head (fb914cb).

Files with missing lines Patch % Lines
pixl_core/src/core/queue/producer.py 89.47% 2 Missing ⚠️
pixl_imaging/src/pixl_imaging/main.py 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #663      +/-   ##
==========================================
+ Coverage   88.41%   89.32%   +0.90%     
==========================================
  Files          81       81              
  Lines        3972     4074     +102     
==========================================
+ Hits         3512     3639     +127     
+ Misses        460      435      -25     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ruaridhg
ruaridhg marked this pull request as ready for review August 21, 2026 14:53

@stefpiatek stefpiatek left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah nice, thanks Ruaridh, appreciate cracking this out. Some structural changes and then happy to a more fine-grained review

Comment thread pixl_core/src/core/anon_queue/_base.py
Comment thread pixl_core/tests/queue/__init__.py
Comment thread pixl_core/tests/patient_queue/__init__.py Outdated
Comment thread orthanc/orthanc-anon/plugin/pixl.py
Comment thread pixl_core/tests/anon_queue/test_subscriber.py
Comment thread orthanc/orthanc-anon/plugin/pixl.py Outdated
Comment thread orthanc/orthanc-anon/plugin/pixl.py Outdated
# Extract the trace context injected into the request headers by the caller, and pass it to
# the thread pool job so the import continues the same trace
headers = {key.lower(): value for key, value in request.get("headers", {}).items()}
headers = {key.lower(): value for key, value in requests.request.get("headers", {}).items()}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh hello, I don't think requests will be able to get any headers. You'll probably need to look at was was in the original headers or ask @p-j-smith

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will have a look and ask @p-j-smith tomorrow if I can't figure it out! I've reduced redundancy in the consumers, producers etc. so hopefully the code is cleaner now (the tests pass apart from the system test)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yeah, so previously the requests auto-instrumentation library injected the headers when calling the ImportStudiesFromRaw endpoint. Now though, the pika auto-instrumentation will handle this - it's installed in the imaging-api Docker Image, and is started when we spin up the container, so this happens automatically.

We can't change the orthanc-anon entrypoint to start the auto-instrumentation libraries, so we need to explicitly call PikaInstrumentor().instrument() so that we can then extract the parent context. We already do this in the CLI:

from opentelemetry.instrumentation.pika import PikaInstrumentor

PikaInstrumentor().instrument()

and we'll need to do the same for orthanc-anon. Then when you need to get the parent context, there is a opentelemetry.context.get_current function you can call to get the parent_context

@stefpiatek stefpiatek left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Ruaridh. Quick review for some feedback, haven't looked in detail at tests. But expect system test is failing because of the requests call that probably fails.

Comment thread pixl_core/src/core/queue/_base.py Outdated
Comment thread pixl_core/src/core/queue/message.py Outdated
Comment thread pixl_core/src/core/queue/subscriber.py Outdated
@ruaridhg
ruaridhg requested a review from stefpiatek September 16, 2026 12:37
Comment thread orthanc/orthanc-anon/plugin/pixl.py Outdated
Comment on lines +246 to +252
data = {
"resource_ids": message.resource_ids,
"series_uids": message.series_uids,
"study_uids": message.study_uids,
"project_name": message.project_name,
"parent_context": parent_context,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_import_studies_from_raw doesn't take a data argument, I think you'll need to keep the same arguments as before (and keep the same names, e.g. study_resource_ids rather than `resource_ids)

@linear-code

linear-code Bot commented Sep 17, 2026

Copy link
Copy Markdown

PIX-68

@ruaridhg
ruaridhg requested a review from p-j-smith September 17, 2026 16:16
@ruaridhg

ruaridhg commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

@p-j-smith more of a review on what's going wrong as the system test is still failing system test is passing, just working on code coverage now

@ruaridhg
ruaridhg force-pushed the 650-anonymisation-reads-from-queue branch from 607eedb to e97ae06 Compare September 18, 2026 13:33

@p-j-smith p-j-smith left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking good. There's also the question of whether we want to make the new queue async, but for a future PR?

Comment thread pixl_core/src/core/queue/subscriber.py Outdated
Comment on lines +119 to +121
# Must match the max_priority PixlConsumer declares this queue with, since
# RabbitMQ rejects redeclaring an existing queue with different arguments.
max_priority=5,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it necessary to pass max_priority here? What happens if you leave the argument out?

Comment thread cli/src/pixl_cli/_config.py Outdated


PRIORITY_QUEUES = {"imaging-primary", "imaging-secondary"}
MAX_QUEUE_PRIORITY = 5

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any harm in also setting the max-priority for the anonymisation queue? It would make it a priority queue, but I assume there's a default priority so we wouldn't need to pass it in or have a way to override it. Only because there's a fair bit of config / logic needed throughout the code to make the anonymisation queue a non-priority queue

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it might be worth leaving in, the original issue stated to leave it out but it has made things more complicated.

@ruaridhg

Copy link
Copy Markdown
Contributor Author

looking good. There's also the question of whether we want to make the new queue async, but for a future PR?

Yeah a future PR would be good, I think it would be easier to switch from sync to async later on as more could be combined but having the structure for sync is maybe useful to include for now

@ruaridhg
ruaridhg requested a review from p-j-smith September 22, 2026 10:38

@stefpiatek stefpiatek left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Ruaridh, looking good to me. A couple of questions and a suggestion for documentation

Comment thread pixl_imaging/README.md Outdated


class PixlConsumer(PixlQueueInterface):
class PixlConsumer[PixlMessage: ImagingRequestMessage](PixlQueueInterface):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love to see some type generics

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though we're not subclassing this, so might be worth just using the exact ImagingRequestMessage type within the class

Comment thread orthanc/orthanc-anon/plugin/pixl.py Outdated
@stefpiatek

stefpiatek commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

looking good. There's also the question of whether we want to #663 (comment), but for a future PR?

I don't think we do want this, because the de-id is an intensive process we'd probably want to spawn child processes to handle it so we're not bound by the same process

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Anonymisation reads from queue

3 participants