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
Fix #1458 - Allow for custom parsing of environment variables via env_parse #3977
Conversation
please review |
Any chance of this getting reviewed any time soon?
|
I appreciate the bump on the review.
I want to limit the scope of this PR to the related issue. If I understand correctly, you can use a validator to transform a simple value instead of using a custom parsing function (which is only necessary when trying to parse from an external source like the environment). While weird, minor modifications like stripping and sanitizing are idiomatic in Pydantic. I might be misunderstanding, though -- discussing the parent issue or a new issue might be in order. |
Ahhh you're right. I hadn't quite digested how all the components could be composed. Still looking forward to this or a similar solution to make customizing complex field-level deserialization less hacky. 😄 |
I'll try to get to this soon. I've been working pretty hard on getting pydantic-core ready for the first released, but I'll try to get back to work on 1.10 soon. |
Looks good, but having reviewed the PR, I think this would be better deal with using suggestion 2 from the original PR: looking for a @acmiyaguchi do you think you could please update the PR? |
Ack, I'll look into implementing the second method this week. Thanks for the review! |
Apologies for being last minute with implementation and discussion here, but I'd like to make a case against option 2:
Suppose I had two fields in a setting class: one of them parses using class Settings(BaseSettings):
my_list: List[str] = Field(env_parse=_parse_custom_list)
my_dict: Dict[int, str] = Field(env_parse=_parse_custom_dict) Whereas suggestion two take on the following look: class BaseSettings:
my_list: List[str]
my_dict: Dict[int, str]
class Config:
@classmethod
def parse_env_var(cls, field, raw_val):
if field == "my_list":
return _parse_custom_list(raw_val)
elif field == "my_dict":
return _parse_custom_dict(raw_val)
return cls.json_loads(raw_val) I personally prefer the former solution in the context of the codebase where I'm currently using pydantic. I want to use a custom parsing function for lists and key-value pairs across several setting classes. Being forced to dispatch the parsing function via I believe the tests in the PR show a bit of flexibility in how parsing could be done with the option on the Field. An alternative to my first implementation above could be done by passing class Settings(BaseSettings):
my_list: List[str] = Field(env_parse=str)
my_dict: Dict[int, str] = Field(env_parse=str)
@validator('my_list', pre=True)
def val_list(cls, v):
assert isinstance(v, str)
return _parse_custom_list(v)
@validator('my_list', pre=True)
def val_dict(cls, v):
assert isinstance(v, str)
return _parse_custom_dict(v) It's a little verbose, but it seems to fit the style of pydantic. |
I've implemented the alternative method via |
please review |
I think your implementation in #4406 is much better, I'm going to close this and accept that PR once a few small things are tweaked.
Having thought about this I'm afraid I disagree. I get that The reasons I prefer
Thanks so much for working on this, and for #4406. I'd love your help more when we get to redesign settings management in V2. |
…se_env_var in Config object (#4406) * Fix #1458 - Allow for custom parsing of environment variables via env_parse * Add docs for env_parse usage * Add changes file for #3977 * fixup: remove stray print statement * Revert env_parse property on field * Add parse_env_var classmethod in nested Config * Update documentation for parse_env_var * Update changes file. * fixup: linting in example * Rebase and remove quotes around imported example * fix example * my suggestions * remove unnecessary Field(env_parse=_parse_custom_dict) Co-authored-by: Samuel Colvin <s@muelcolvin.com>
Change Summary
This PR adds an
env_parse
extra into Fields to allow for custom parsing of the environment within Settings. This is useful when specifying a custom format in environment strings e.g. lists (1,2,3
) or key-value pairs (a=1,b=2,c=3
). String-encoded JSON is not ideal in certain situations, such as when the environment is specified inside of a YAML file (leading to string-escaped string-encoded JSON).Related issue number
fixes #1458
Checklist
changes/<pull request or issue id>-<github username>.md
file added describing change(see changes/README.md for details)