Как передать переменные окружения в команду Django?
У меня есть API на Django с Poetry, которое я запускаю с помощью Pycharm'а. В Pycharm'е я установил все переменные и всё нормально запускается и работает.
Но когда я запускаю команду python manage.py runserver
в терминале, возвращается django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.
. То есть он не видит переменные, потому что я их и не передавал). Но если перед командой задать переменные с помощью set DJANGO_SECRET_KEY="..."
, то тоже ничего не работает.
С чем это может быть связано? Если через кнопку запуска в Pycharm'е всё работает, то почему не работает в терминале?
set KEY=VAL
работает - проверил с помощью echo $KEY
.
Например, можно использовать пакет pydantic-settings (документация), в модели описать поля, их типы, дефолтные значения. При наличии соответствующих значений в переменных окружения они заменят значения по умолчанию, при этом значения сконвертируются в соответствии с аннотациями типа в модели.
Пример:
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "app"
app_host: str = "localhost"
app_port: int = 8000
settings = Settings()
print(settings)
print(type(settings.app_port))
# app = FastAPI(title=settings.app_name)
def main():
...
# uvicorn.run(app, host=settings.app_host, port=settings.app_port)
if __name__ == "__main__":
main()
Вывод при запуске без записи в переменные окружения:
> python test.py
app_name='app' app_host='localhost' app_port=8000
<class 'int'>
Вывод с передачей значения через переменную окружения (запускаю на linux):
> env APP_PORT=9876 python test.py
app_name='app' app_host='localhost' app_port=9876
<class 'int'>
Кроме переменных окружения поддерживаются .env
файлы, см. там же: Dotenv (.env) support
Если $env:APP_PORT="9000"
помогает передать переменную внутрь окружения poetry
(насколько мне подсказывает гугл, это способ для powershell), то его и используете.
Также можно установить плагин poetry-dotenv-plugin
для poetry
:
poetry self add poetry-dotenv-plugin
тогда можно будет не устанавливать переменные окружения вручную, а прописать их в .env
файле, что-то типа
APP_NAME=application
APP_HOST=0.0.0.0
APP_PORT=9000
Этот вариант удобен, если нужно указать несколько значений.
По второй части: переменные окружения всегда хранят строки. Если нужно получить число, вам конкретное значение нужно конвертировать в число, и способ через int(os.getenv("APP_PORT", 8000))
, который вы упоминаете,- вполне рабочий вариант.
Если не нравится оборачивание в int()
, например, можно использовать пакет pydantic-settings (документация), в модели описать поля, их типы, дефолтные значения. При наличии соответствующих значений в переменных окружения они заменят значения по умолчанию, при этом значения сконвертируются в соответствии с аннотациями типа в модели.
Пример:
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "app"
app_host: str = "localhost"
app_port: int = 8000
settings = Settings()
print(settings)
print(type(settings.app_port))
# app = FastAPI(title=settings.app_name)
def main():
...
# uvicorn.run(app, host=settings.app_host, port=settings.app_port)
if __name__ == "__main__":
main()
Вывод при запуске без записи в переменные окружения:
> python test.py
app_name='app' app_host='localhost' app_port=8000
<class 'int'>
Вывод с передачей значения через переменную окружения (запускаю на linux):
> env APP_PORT=9876 python test.py
app_name='app' app_host='localhost' app_port=9876
<class 'int'>
Кроме переменных окружения поддерживаются .env
файлы, см. там же: Dotenv (.env) support, это будет работать и без установки плагина poetry-dotenv-plugin
.