Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support inject for default plan arguments again #773

Merged
merged 1 commit into from
Jan 15, 2025

Conversation

tpoliaw
Copy link
Contributor

@tpoliaw tpoliaw commented Jan 9, 2025

Let inject work again by using all fields of the built pydantic model including the default ones provided by inject

Fixes #647, #633

Instructions to reviewer on how to test:

  1. Run plan that uses inject for default parameters, (eg blueapi controller run stp_snapshot '{"detectors":["x"]}' to run the plan from example_plans)
  2. See that the plan runs correctly with sample_temperature and sample_pressure. (It may fail at the end of the run with a different error relating to path providers for the detector but this is unrelated).
  3. If a plan is created using inject("<misssing_device_name>") (as for Blueapi context should except when it can't find an injected device  #633), the plan will not be accepted and blueapi will return 422 Unprocessable Entity. The detailed error message is generated for this but it's not immediately obvious how to access it. Either way, that should be its own issue.

Checks for reviewer

  • Would the PR title make sense to a user on a set of release notes

Copy link

codecov bot commented Jan 9, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 93.36%. Comparing base (3e36c8c) to head (de4b5e2).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #773      +/-   ##
==========================================
+ Coverage   93.32%   93.36%   +0.04%     
==========================================
  Files          38       38              
  Lines        2083     2081       -2     
==========================================
- Hits         1944     1943       -1     
+ Misses        139      138       -1     

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

Copy link
Contributor

@callumforrester callumforrester left a comment

Choose a reason for hiding this comment

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

Nice, thanks!

Is it feasible/worthwhile to write a regression test?

src/blueapi/worker/task.py Outdated Show resolved Hide resolved
@tpoliaw tpoliaw force-pushed the default_arg_conversion branch from cbc830f to 34d501f Compare January 10, 2025 12:20
@tpoliaw
Copy link
Contributor Author

tpoliaw commented Jan 10, 2025

Added a couple of tests to cover the 'normal' use and the failure case in 633. They're in test_task_worker for now as there isn't a test_task module and they re-use the context fixture from that module.

@tpoliaw tpoliaw force-pushed the default_arg_conversion branch from 34d501f to be46b33 Compare January 10, 2025 13:19
@tpoliaw tpoliaw requested a review from noemifrisina January 13, 2025 10:01
Copy link
Contributor

@callumforrester callumforrester left a comment

Choose a reason for hiding this comment

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

LGTM!

@callumforrester
Copy link
Contributor

Tagging @olliesilvester for awareness

When preparing the parameters for a plan, pydantic creates an instance
of the dynamically generated BaseModel, relying on the 'Reference' types
to convert from strings to instances of the devices. This includes
strings that are used as default field values (default parameters
created using the `inject` method).

We then convert the model back to a dictionary to pass as kwargs to the
plan. The previously used `model_fields_set` field on the model only
iterates over the fields set via the input JSON (the user supplied
arguments) and skips the fields populated via the default factories in
the base model. Using the `__pydantic_fields__` class variable, allows
all fields to be used including the defaults. This was previously
avoided as it generated warnings for unknown types but it is possible to
opt-out of these warnings.
@callumforrester callumforrester merged commit efcb4aa into main Jan 15, 2025
31 checks passed
@callumforrester callumforrester deleted the default_arg_conversion branch January 15, 2025 11:24
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.

inject not working on i04
2 participants