FastAPI не видит новый .env: настройки и кэш Settings
В .env поменяли адрес сервиса, а FastAPI продолжает обращаться по старому. Файл на диске правильный, опечаток нет. Прежде чем снова пересобирать весь проект, стоит выяснить три вещи: откуда процесс получает переменную, когда он читает файл и хранит ли уже готовый объект настроек.
Это разные источники старого значения. Переменная процесса может перекрывать .env. Файл может искаться в другом рабочем каталоге. А закэшированный Settings может вообще больше не читать ни файл, ни окружение.
Настройки создаются в определённый момент
Установите python -m pip install pydantic-settings. Этот пример можно запустить отдельно от FastAPI:
import os
from functools import lru_cache
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_prefix="DEMO_", env_file=".env")
service_name: str = "catalog"
@lru_cache
def get_settings():
return Settings()
os.environ["DEMO_SERVICE_NAME"] = "first"
print(get_settings().service_name)
os.environ["DEMO_SERVICE_NAME"] = "second"
print(get_settings().service_name)
get_settings.cache_clear()
print(get_settings().service_name)
Вывод: first, first, second. Во втором вызове возвращается прежний объект. cache_clear здесь нужен для опыта; в рабочем сервисе не стоит превращать его в публичную кнопку произвольного обновления секретов.
Как искать источник значения
Сначала проверьте рабочий каталог процесса и наличие ожидаемого файла. Затем выясните, передаёт ли Docker Compose, systemd или оболочка ту же переменную непосредственно в окружение. В стандартном порядке источников pydantic-settings значение окружения приоритетнее .env; настройка источников в самом проекте может этот порядок изменить.
Для диагностики используйте безопасное поле вроде имени окружения или адреса без учётных данных. Печатать весь Settings, DATABASE_URL с паролем или содержимое .env в журнал не нужно.
Редактирование .env не меняет окружение уже запущенного процесса. Если секрет передаёт система запуска, обновите его там и перезапустите процесс штатным способом. У каждого воркера свой объект настроек, поэтому обновиться должны все нужные экземпляры.
Что проверять в тестах
Тест, меняющий окружение через monkeypatch, может получить кэш от предыдущего теста. Очищайте get_settings.cache_clear() до создания проверяемого объекта и после теста. Иначе тесты зависят от порядка запуска.
Полезно разделить тест приоритетов источников и тест потребителя настроек. Первому нужен настоящий Settings, второму часто достаточно подмены зависимости FastAPI. Смежный случай на уровне контейнеров — почему Compose использует старое значение окружения.
Собрать следующий этап проекта
Если проект уже вырос из одного файла, пригодится следующий шаг: разделить код на пакеты, описать интерфейсы типами и покрыть поведение тестами. Этому посвящён бесплатный курс Python для продвинутых: от объектной модели до небольшого приложения с конфигурацией и логированием.
Посмотреть программу: Python для продвинутых: ООП, типизация и тестирование
Проверить детали: FastAPI: Settings и кэш, Pydantic Settings.
Продолжить на практике
- Python для продвинутых: ООП, типизация и тестирование ↗
Практический курс-мост от базового Python к разработке поддерживаемых приложений. Вы разберётесь со структурой пакетов, объектной моделью, современной типизацией и автоматическими тестами, а затем соедините эти инструменты в небольшом приложении с хранением данных и логированием.
- FastAPI для начинающих: API с базой данных и тестами ↗
Соберёте свой первый полноценный backend на FastAPI: с базой данных, регистрацией, JWT-авторизацией и автотестами. 34 коротких урока и 140 заданий с проверкой — бесплатно.
