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
allow use of a .env
-style files in BaseSettings (#607)
#1011
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1011 +/- ##
========================================
Coverage ? 100%
========================================
Files ? 20
Lines ? 3507
Branches ? 683
========================================
Hits ? 3507
Misses ? 0
Partials ? 0
Continue to review full report at Codecov.
|
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.
Looking good.
Also needs tests and documentation.
- allow specifying `_env_file` kwarg in instantiation * overrides any `env_file` specified in the `Config` class - cast `os.environ` as a dict for better consistenty of behavior - `env_path` should be a `Path` type - replace `with open()` with `read_text` - use regex for parsing the dotenv files and throw error on invalid line - factor out `read_env_file` into separate file for easier testing
Still haven't written any tests yet, but I figure it's best to leave that until we've settled on the rest of the implementation. |
Sorry to highjack the PR, I'm currently having a simple function to push .env fies into objects inheriting BaseSettings using Stuff like this for instance:
maybe the "loading" part could take inspiration from it, just an idea, well either way that's a good idea and will reduce dependencies so thankls for that ! |
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.
Also need tests and documentation.
@euri10 Thanks for the suggestion! I think in the end the But yeah, since Settings handling is a first-class use-case of Pydantic, I felt that it was much nicer to have it integrated into the lib without dependencies. |
Ok, I think I've sorted everything on the PR checklist. Let me know if anything else needs changing. |
#### `.env` | ||
|
||
``` | ||
# ignore comment |
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.
I think this needs an example of python code to read this file so the stripping of quotes etc. is shown.
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.
As in just include the actual code we're using to parse env files in the docs, or...?
tests/env_files/test_settings_1.env
Outdated
@@ -0,0 +1,6 @@ | |||
# this is a comment |
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.
Better to use tmp_path
than create actual files like this.
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.
Is it? It creates a lot of repetition in the tests since we're testing various different things but can re-use the same files. Will make the changes though if you think it is worth it.
@samuelcolvin Do we really want existing environment variables to take precedence over the One of the major benefits of using That makes the most sense to me, as otherwise you might have a bunch of vars in this file you're loading that are silently ignored, which seems like it would do more harm than good. |
Don't quote me because on that, I'm not too sure about it, but I think in python-dotenv you need to be explicit about precedence using the override kwarg. |
No, environment variables should definitely take precedence over variables in
|
That's what the env variable prefix is for. |
Hi @acnebs, are you still okay to finish this? |
@samuelcolvin Yep, just been a bit busy over the past couple weeks. Should be able to get to it soon. |
Any news about that PR? I'm pretty excided about getting rid of my custom |
me too, if there's no progress I'll try and finish it myself when I get a chance. @sm-Fifteen if you'd like to take over this, by all means create a new PR from this work. I'll make sure we give credit to both developers. |
Co-Authored-By: Samuel Colvin <samcolvin@gmail.com>
Sorry about the long delay, getting back to this now! |
Looking at the code more closely, shouldn't we just use I just checked and
import dotenv
# A dict, which can then be used to populate BaseSettings
env_dict = dotenv.dotenv_values('.env') EDIT: See theskumar/python-dotenv#170 for some of the differences between parsers. |
No. For reasons I think I explained above. We can cover 99.9% of usage very easily, if you want more you should probably use yaml or toml. |
upon reflection, I've decided to take on @sm-Fifteen's comment and switch to using python-dotenv. While I don't like the extra (optional) dependency for one use, I can't ignore the problems you discuss regarding quotes etc. @acnebs I'm sorry we spent so long building a dotenv parser that's now not being used, but I really do think this is a better approach. |
I'm not seeing tests for types other than strings, does the current implementation support other types of field, such as ints, floats, booleans, optionals and possibly JSON-formatted |
Yes of course, same as pydantic always does. Those values will be coerced to the field's type. There is definitely at least one test which demonstrates this. Lists etc. would require the |
Yeah, ok, thank you for confirming this. That pretty much covers what I needed this to do, then. |
@samuelcolvin Sounds good. Thanks for finishing it up! |
Mention of this was removed in v1 and this PR breaks code which relied on |
sorry about that I wasn't aware that PR welcome if you wish to update the release notes to include this. |
Would you also accept a PR to allow customising the evaluation order in a future version? |
I guess, though I imagine it could be quite complex. Quite related: I also want to allow multiple dot-env files with different priorities which are then merged, same as CRA. |
Change Summary
Update
BaseSettings
class to allow the use of.env
-style files for storing sensitive environment variables.Just pass in the path (either absolute or relative to the working directory) to such a file in the Config subclass, and pydantic will do the rest for you.
.env
settings.py
test.py
Related issue number
#607
Checklist
changes/<pull request or issue id>-<github username>.md
file added describing change(see changes/README.md for details)