-
Notifications
You must be signed in to change notification settings - Fork 6
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
add env loading #649
add env loading #649
Conversation
slightly unclear where should the default values come from at the moment the ConfigLoader just starts with all is none and gets updated through the file first |
this needs to be changed because at the moment the tests are failing because of the config loading error@ |
regarding the |
harder to test, as the debugger does not pick up the client changes. they do not propagate correctly to the client object from the CLI, though config is called |
OTOH the stomp-loading error is bizarre, and the
|
for the third of the failing tests, maybe the config is not loaded fully before the assertion is called? let's check if the cli:main line for |
it must be the cli OR env values that override (incorrectly) the prior |
not quite, it's not overriding, it's just that the |
I forgot the assignment after making a pure function: self._values = recursively_updated_map(self._values, values) |
ok actually the last test might be failing due to other kinds of config being invalid, not the
|
thus it comes back to the question of class RestConfig(BlueapiBaseModel):
host: str = "localhost"
port: int = 8000
protocol: str = "http" |
Not sure, if this is the answer you looking for but these are default value inside uvicorn so if you leave it blank when you do run these will be the default value so I guess we just bring it up to so it changeable. |
Cool, I didn't realize the uvicorn connection, thanks |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #649 +/- ##
==========================================
+ Coverage 92.62% 92.76% +0.14%
==========================================
Files 35 35
Lines 1654 1700 +46
==========================================
+ Hits 1532 1577 +45
- Misses 122 123 +1 ☔ View full report in Codecov by Sentry. |
yay it works! |
Thanks @callumforrester for the review, I'll implement shortly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely needs docs on how to use this. I can't see a way of passing options to the CLI that aren't blocked as unrecognised by click. It would also be good to have a list of options that are expected or available
src/blueapi/config.py
Outdated
for key, value in os.environ.items(): | ||
if key.startswith(prefix): | ||
# Convert key to a config path-like structure | ||
config_key = key[len(prefix) :].lower() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
config_key = key[len(prefix) :].lower() | |
config_key = key.removeprefix(prefix).lower() |
Should this also use the same method as the CLI parsing? eg BLUEAPI_CONFIG_FOO=bar
sets values['config']['foo'] = "bar"
instead of relying on eval (which presumably requires something like BLUEAPI.CONFIG='{"foo": "bar"}'
)?
src/blueapi/config.py
Outdated
raise InvalidConfigError( | ||
"Something is wrong with the configuration file: \n" | ||
f"""Something is wrong with the configuration file: | ||
{pretty_error_messages}""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this end up with the first error being weirdly indented?
tests/unit_tests/test_config.py
Outdated
new = {"a": {"y": 20, "z": 30}, "c": 4} | ||
expected = {"a": {"x": 1, "y": 20, "z": 30}, "b": 3, "c": 4} | ||
result = recursively_updated_map(old, new) | ||
assert result == expected, f"Expected {expected}, but got {result}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this also test that old wasn't modified?
d28ee9a
to
6213805
Compare
nice, I haven't thought of this lambda use Co-authored-by: Peter Holloway <[email protected]>
6213805
to
138a096
Compare
actually there should be a package for that |
@DominicOram please take a look at the examples for this https://github.com/PasaOpasen/py-env-parser?tab=readme-ov-file#examples if it's not right, the logic is just 200 lines of code so we could copy paste into this repo and adjust should we want to modulate the API - but arguably this would be useful across DLS |
Not sure if this help or not, I think pydantic has something call setting management that allow you to pick up env variable if it is missing. and you can just do something like BaseSettings().dict() to get the dictionary out. But of cause you will have to already have a pydantic baseModel for the data you want to parse. |
@Relm-Arrowny it's worth looking into but I'm not sure how well it works for nested data |
@callumforrester it promises a pretty good level of support. https://docs.pydantic.dev/latest/concepts/pydantic_settings/#nested-model-default-partial-updates thanks @Relm-Arrowny for finding this, as a feature of pydantic it looks more solid than the library I found |
As just a user of BlueAPI I don't have strong or well-informed opinions about implementation details and I feel like any opinion I do give will just muddy the water. So I defer to @callumforrester and @tpoliaw as the maintainers of BlueAPI to make any decisions around this issue. |
closing as the implementation with pydantic will be entirely different https://docs.pydantic.dev/latest/concepts/pydantic_settings/#parsing-environment-variable-values |
No description provided.