Pydantic не отдает приоритет среде ОС

Я пытаюсь реализовать правильное управление переменными среды в средах разработки, производства и промежуточной среды. Использование Pydantic имеет решающее значение, поскольку Pydantic присутствует повсюду в приложении.

Тестирование этого приложения становится сложной задачей из-за настройки переменных среды на основе операционной системы в производственной среде и среде разработки.

У меня есть следующее:

from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict

from devtools import debug


class Config(BaseSettings):

    # Environment
    STAGE: str = Field('prod', validation_alias='STAGE')
    OTHER: str

    model_config = SettingsConfigDict(env_file='.test.env', env_file_encoding='utf-8', env_prefix='DEV_')


settings = Config()

debug(settings)

с файлом .test.env, который выглядит так:

STAGE=test
DEV_OTHER = "other"

и я установил переменную среды ОС следующим образом:

export STAGE=dev

давая следующий ответ с printenv:

...
STAGE=dev
...

и затем получите следующий вывод:

test.py:18 <module>
    settings: Config(
        STAGE='test',
        OTHER='other',
    ) 

В Pydantic переменная среды ОС будет иметь приоритет, но здесь этого не происходит, поскольку установка переменных среды в среде разработки связана с процессом.

Это приводит к неожиданному поведению с настройками Pydantic. Есть ли обходной путь? Я не хочу устанавливать STAGE в файле bash и перезапускать среду (что обычно означает перезагрузку компьютера) всякий раз, когда я хочу проверить поведение в разных средах.

Если вы не загружаете файл .test.env в реальные переменные среды, они там не будут присутствовать. Класс pydantic BaseSettings только загружает файл и анализирует содержимое в объект pydantic. Он не изменяет переменные среды. От них тоже не загружается.

lord_haffi 26.06.2024 20:22

Хорошо, не уверен, что я следую. Файл .test.env загружается, поскольку я могу получить доступ ко всем его значениям через объект Config(). У меня также есть переменная STAGE, объявленная как переменная env ОС, которая также присутствует в .test.env. Согласно документации Pydantic я ожидаю, что первое будет иметь приоритет, но это не так. >> «Даже при использовании файла dotenv pydantic по-прежнему будет читать переменные среды, а также файл dotenv, переменные среды всегда будут иметь приоритет над значениями, загруженными из файла dotenv».

Paul 26.06.2024 20:40

Извините моя ошибка. Вы правы, pydantic загружает и расставляет приоритеты значений из среды. Но я на самом деле не могу воспроизвести вашу проблему. На моей машине приоритет имеет переменная env. Вы на 100% уверены, что переменная среды присутствует во время выполнения? Не могли бы вы проверить, например? print(os.getenv("STAGE"))?

lord_haffi 26.06.2024 21:32

Как вы используете Python? Вы уверены, что процесс Python наследует переменные среды? Что, если поставить import os; print(os.environ) вверху файла?

juanpa.arrivillaga 27.06.2024 01:01

Да, это странно. os.environ.get('STAGE') возвращает None, однако printenv возвращает STAGE=prod даже с export STAGE=prod, что должно сделать переменную доступной для всех подпроцессов. Даже если я закрою все процессы, связанные с Python, export переменную и перезапущу процесс Python, все равно ничего.

Paul 27.06.2024 09:59
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема связана не с Pytdantic, а с видимостью переменных среды и соответствующих процессов, в которых они создаются, как упоминается в juanpa.arrivillaga и lord_haffi. Переменная, созданная с помощью export в оболочке, доступна только этой оболочке и любому подпроцессу этой оболочки. Его необходимо сохранить, добавив в ~/.zshrc или что-то подобное, прежде чем он станет доступен другим процессам.

Традиционно .zshrc и подобные — это подходящее место для вещей, которые не передаются через среду (например, PS1 и другие неэкспортируемые конфигурации оболочки). Традиционный способ UNIX гласит, что переменные среды входят в .profile/.zprofile/и т. д., поэтому они устанавливаются только один раз при создании оболочки входа и не запускаются повторно для каждой интерактивной оболочки, созданной как подпроцесс этой оболочки входа.

Charles Duffy 27.06.2024 13:48

Другие вопросы по теме