Closed tedsecretsource closed 2 months ago
Thanks @tedsecretsource for reporting the issue.
from the doc:
If you need to load multiple dotenv files, you can pass multiple file paths as a tuple or list. The files will be loaded in order, with each file overriding the previous one.
Here is an example of passing multiple .env files:
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(
# `.env.prod` takes priority over `.env`
env_file=('.env', '.env.prod')
)
Thanks @hramezani. Note that I'm not trying to load multiple files, just one file. I just want to load .env.testing
. Are you suggesting that the way to do this would be something like: env_file=('.env', '.env.testing')
so that, in production, where no .env.testing file exists, only .env would be loaded while on my local machine, where .env.testing does exist, it would override values in .env? If that's true, maybe that could work but the documentation also states pretty clearly:
settings = Settings(_env_file='prod.env', _env_file_encoding='utf-8')
but if I do the above replacing prod.env
with .env.testing
, .env
always ends up loading and .env.testing
never does.
You all need more context…
I'm doing this in FastAPI.
# File main.py (abbreviated)
def init_settings():
return Settings(_env_file='.env.testing')
@app.post("/gpt/v1/q")
async def query_gpt(
request: Request,
settings: Annotated[Settings, Depends(init_settings)],
):
"""Query the index."""
return {"settings": settings}
and then in the test:
app.dependency_overrides[init_settings] = lambda: Settings(_env_file='.env.testing')
def test_gpt_api_returns_200():
response = client.post(
url="/gpt/v1/q",
data={"query": "What is Python?"},
)
assert response.status_code == 200
And the values in the settings dict are always from the .env
file and not from .env.testing
. I cannot for the life or me understand what I am doing wrong.
with one file it should be ok. I didn't get the problem. if you include a file name in _env_file
, pydantic-settings
should only loads that file and use the values from the file.
If it doesn't work, probably you already have some variable on your system environment that overrides the value from the file.
BTW, please create an example code and let me know how to reproduce the problem.
probably you already have some variable on your system environment that overrides the value from the file
The output of env
does not show any of the values in the .env.testing
file, only normal server-related keys and values.
BTW, please create an example code and let me know how to reproduce the problem.
I really appreciate the offer. I was hoping to avoid this but I can't see any way around it :( I'll see what I can do. Thanks for the offer.
Problem solved!
We had this line in one of the included files (vestige of a prior version before using pydantic-settings):
load_dotenv(find_dotenv())
Naturally, that was putting the .env variables into the actual environment and overwriting anything we were sending in .env.testing… Live and learn 🤷
Thanks for your help and I certainly hope this helps someone else in the future!
Without going into too much detail, is there a reason why I am unable to load a specific environment file if a
.env
file exists in the project? In other words…Given I am in my testing environment and both a
.env
and a.env.testing
files exist with valid entries When I load my settings usingsettings = Settings(_env_file=".env.testing")
Thensettings.app_env
= 'testing'However,
settings.app_env
= 'production' (because that is what is in the.env
file).What in the world am I missing? What could I possibly be doing wrong?
FWIW the actual use case is a bit more complex than this but this is the behavior that seems to be happening. Any pointers would be greatly appreciated 🙏
Ted