pydantic icon indicating copy to clipboard operation
pydantic copied to clipboard

feat: add support multiple dotenv files (#1497)

Open rekyungmin opened this issue 2 years ago • 9 comments

Change Summary

Allow BaseSettings to accept multiple .env files in Config as a list or tuple. The first value takes priority over the second value.

Example:

.env file:

debug_mode=true
host=localhost
port=8000

.env.prod file:

debug_mode=false
host=https://example.com/services

test code:

from pydantic import BaseSettings


class Settings(BaseSettings):
    debug_mode: bool
    host: str
    port: int

    class Config:
        # `.env.prod` takes priority over `.env`
        env_file = ['.env.prod', '.env']
        env_file_encoding = 'utf-8'

s = Settings()
print(s.dict())
# {'debug_mode': False, 'host': 'https://example.com/services', 'port': 8000}

Related issue number

#1497

Checklist

  • [X] Unit tests for the changes exist
  • [X] Tests pass on CI and coverage remains at 100%
  • [X] Documentation reflects the changes where applicable
  • [X] changes/<pull request or issue id>-<github username>.md file added describing change (see changes/README.md for details)
  • [X] My PR is ready to review, please add a comment including the phrase "please review" to assign reviewers

rekyungmin avatar Sep 16 '21 13:09 rekyungmin

please review

rekyungmin avatar Sep 16 '21 13:09 rekyungmin

Please update.

samuelcolvin avatar Dec 08 '21 22:12 samuelcolvin

please review

rekyungmin avatar Dec 21 '21 00:12 rekyungmin

please update.

samuelcolvin avatar Dec 24 '21 13:12 samuelcolvin

Thanks for the review. Please review.

rekyungmin avatar Dec 26 '21 06:12 rekyungmin

@rekyungmin @samuelcolvin IMO this is counterintuitive, I would expect the files to be loaded in the order in which they are defined which would mean the last one in the list gets the final say. So instead of this:

for f in reverse(env_file):
    props = load_dotenv(f)

I would expect this:

for f in env_file:
    props = load_dotenv(f)

This also matches the semi-documented behavior for multiple sources in python-dotenv.

As long as it's consistent I suppose not a huge deal either way, I'm just excited to see this feature!! What's left here to merge?

phillipuniverse avatar Feb 11 '22 14:02 phillipuniverse

@rekyungmin @samuelcolvin IMO this is counterintuitive, I would expect the files to be loaded in the order in which they are defined which would mean the last one in the list gets the final say. So instead of this:

for f in reverse(env_file):
    props = load_dotenv(f)

I would expect this:

for f in env_file:
    props = load_dotenv(f)

This also matches the semi-documented behavior for multiple sources in python-dotenv.

As long as it's consistent I suppose not a huge deal either way, I'm just excited to see this feature!! What's left here to merge?

In Python, it is common for the rightmost value to win (e.g. unpacking, dict union). However, in customize_sources, the leftmost value wins. I think the left win strategy is better for consistency in the settings module.

@samuelcolvin, what do you think?

rekyungmin avatar Mar 09 '22 06:03 rekyungmin

Hey, any news on this PR? would love to see it merged! :)

lucafaggianelli avatar Jul 12 '22 12:07 lucafaggianelli

please update.

samuelcolvin avatar Aug 04 '22 14:08 samuelcolvin

Thanks @rekyungmin for this, and everyone for your feedback.

samuelcolvin avatar Aug 12 '22 12:08 samuelcolvin