Migrate BeamlineParameters to use config server#1773
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1773 +/- ##
==========================================
+ Coverage 99.04% 99.06% +0.01%
==========================================
Files 308 313 +5
Lines 11672 11720 +48
==========================================
+ Hits 11561 11610 +49
+ Misses 111 110 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
DominicOram
left a comment
There was a problem hiding this comment.
Thanks, this looks good, some comments in code. This also means that we are now reliant on the config server so I think we need to do DiamondLightSource/mx-bluesky#478 before we put this on the beamline. Would you be able to pick that up and put in a meeting with Neil, Mark, Rob and Myself?
| from dodal.log import LOGGER | ||
| from dodal.utils import get_beamline_name | ||
|
|
||
| BEAMLINE_PARAMETER_KEYWORDS = ["FB", "FULL", "deadtime"] |
There was a problem hiding this comment.
Should: This list is no longer used, can we remove it?
| ) | ||
|
|
||
|
|
||
| def get_beamline_parameters(beamline_param_path: str | None = None): |
There was a problem hiding this comment.
Could: This is a bit of scope creep but the way we're doing this is a bit messy. I think we can do it like we do
dodal/src/dodal/beamlines/i03.py
Line 92 in d245f0a
There was a problem hiding this comment.
This makes sense. So when devices need beamline parameters and before would have called get_beamline_parameters(), I'm guessing now they'd be passed in when the device is constructed.
How would this work when we need to get beamline parameters inside common plans? Or should these params always be attached to devices by that point?
There was a problem hiding this comment.
So when devices need beamline parameters and before would have called get_beamline_parameters(), I'm guessing now they'd be passed in when the device is constructed.
Yes
How would this work when we need to get beamline parameters inside common plans? Or should these params always be attached to devices by that point?
Yh, that is a bit harder. I think we would need to have a look at it, which maybe means it should be in another issue
There was a problem hiding this comment.
Maybe a similar thing can be done for the config server itself? So have a get_config_server() in every ixx.py that returns a config client set up for that beamline
| return cls(params=dict(config_pairs)) | ||
|
|
||
| @classmethod | ||
| def from_file(cls, path: str): |
There was a problem hiding this comment.
Nit: It's a little misleading that this is still called from_file when it's not reading directly from the file
| @classmethod | ||
| def parse_value(cls, value: str): | ||
| return ast.literal_eval(value.replace("Yes", "True").replace("No", "False")) | ||
| config_server = ConfigServer(url="https://daq-config.diamond.ac.uk") |
There was a problem hiding this comment.
Should: Can you pull the URL into a constant? From DiamondLightSource/mx-bluesky#478 (comment) it may be that we will need it to be beamline specific too
tests/conftest.py
Outdated
| print(contents) | ||
| if desired_return_type is str: | ||
| return contents | ||
| elif desired_return_type is dict: | ||
| print("return type is dict") |
There was a problem hiding this comment.
Should: Remove print statements
tests/conftest.py
Outdated
| elif desired_return_type is dict: | ||
| print("return type is dict") | ||
| return json.loads(contents) | ||
| elif issubclass(desired_return_type, ConfigModel): # type: ignore |
There was a problem hiding this comment.
Should: As far as I can see we're never trying to return a ConfigModel so why do we need this bit? Or is it for later PRs?
There was a problem hiding this comment.
Yeah this is for later PRs. We either get a dict or a ConfigModel depending on what we request from the server, other config like LUTs or display config will be returned as a subclass of ConfigModel, this fixture emulates that
c87a30e to
3dbb881
Compare
| def _load_topup_configuration_from_properties_file() -> dict[str, Any]: | ||
| params = get_beamline_parameters() | ||
| return params.params | ||
| params = get_beamline_parameters(get_beamline_name("i03")) |
There was a problem hiding this comment.
I don't really like this practice that we have in the code of inserting arbitrary default beamline names into random bits of code. By removing the default from get_beamline_parameters() this has just spread it around more.
I think it would be better if we never assumed it anywhere in production code and instead took it from the BEAMLINE environment variable in a single function which we can patch out for unit tests.
There was a problem hiding this comment.
So basically remove the 'default' argument from get_beamline_name()?
There was a problem hiding this comment.
I've had a quick go at doing this and it's looking like a big change, and I'm not 100% sure of the consequences, so I think we should pull it out into a new issue. For now, I'll make the default argument optional so that we don't have to arbitrarily decide on defaults.
| # Nb this parameter is misleadingly named to confuse you | ||
| self.dcm_fixed_offset_mm = get_beamline_parameters( | ||
| daq_configuration_path + "/domain/beamlineParameters" | ||
| get_beamline_name("i03"), |
There was a problem hiding this comment.
Why is undulator special, it's the only one that uses the extra parameter on get_beamline_parameters(), isn't it just getting the same beamline parameters file that everything else uses? The only other places it's used are tests.
I think we should drop the filename argument unless you can think of a good reason to keep it.
|
|
||
|
|
||
| def test_get_beamline_parameters_works_with_no_environment_variable_set(): | ||
| def test_get_beamline_parameters_errors_with_no_environment_variable_set(): |
There was a problem hiding this comment.
Probably best to do something like patch.dict(environ, {k: v for k, v in environ.items() if k != "BEAMLINE"}, clear=True) if only to avoid any possibility of strange downstream effects from mutating our environment (although we should hopefully be agnostic to this environment variable)
There was a problem hiding this comment.
or perhaps even simpler use monkeypatch as you have used below
|
|
||
|
|
||
| def test_get_beamline_parameters_works_with_no_environment_variable_set(): | ||
| def test_get_beamline_parameters_errors_with_no_environment_variable_set(): |
There was a problem hiding this comment.
This test doesn't actually do what it says on the tin - because we specify the beamline parameter it never errors.
rtuck99
left a comment
There was a problem hiding this comment.
Approved, subject to fixing test to cover the error condition, and minor observation about environment
Fixes DiamondLightSource/mx-bluesky#1504
Required by DiamondLightSource/mx-bluesky#1511
Instructions to reviewer on how to test:
Checks for reviewer
dodal connect ${BEAMLINE}