So, Im trying to setup Alembic with FastAPI and Im having a problem with Pydantic's BaseSettings, I get a validation error (variables not found) because it doesnt find the .env file (?)
It can be solved by changing env_file = ".env"
to env_file = "../.env"
in the BaseSettings
class Config
but that makes the error happen when running main.py, I tried setting it as an absolute path with env_file = os.path.abspath("../../.env")
but that didnt work.
What should I do?
config.py:
import os
from functools import lru_cache
from pydantic_settings import BaseSettings
abs_path_env = os.path.abspath("../../.env")
class Settings(BaseSettings):
APP_NAME: str = "AppName"
SQLALCHEMY_URL: str
ENVIRONMENT: str
class Config:
env_file = ".env" # Works with uvicorn run command from my-app/project/
# env_file = "../.env" Works with alembic command from my-app/alembic
# env_file = abs_path_env
@lru_cache()
def get_settings():
return Settings()
Project folders:
my-app
├── alembic
│ ├── versions
│ ├── alembic.ini
│ ├── env.py
│ ├── README
│ └── script.py.mako
├── project
│ ├── core
│ │ ├── __init__.py
│ │ └── config.py
│ └── __init__.py
├── __init__.py
├── .env
└── main.py
For me it was the fact that .env
was not in the same directory as the running script.
I had to manually anchor the .env
file to an absolute path.
Here is my settings.py
file with .env
residing alongside in the same directory:
import os
from pydantic_settings import BaseSettings, SettingsConfigDict
DOTENV = os.path.join(os.path.dirname(__file__), ".env")
class Settings(BaseSettings):
pg_dsn: str
pg_pool_min_size: int
pg_pool_max_size: int
pg_pool_max_queries: int
pg_pool_max_intactive_conn_lifetime: int
model_config = SettingsConfigDict(env_file=DOTENV)
So with the os.path.join(os.path.dirname(__file__), ".env")
line I basically instruct to search for .env
file inside the same directory as the settings.py
file.
This way you can run any of your scripts, and the Settings
object will always point to your .dotenv
file.