从环境文件中读取环境变量

时间:2016-10-24 10:36:45

标签: python docker

我想在本地环境中运行Python脚本,该脚本通常在Docker容器中运行。 docker-compose.yml指定env_file,其外观(部分)如下所示:

DB_ADDR=rethinkdb
DB_PORT=28015
DB_NAME=ipercron

为了在本地运行,我将这些行转换为

os.environ['DB_ADDR'] = 'rethinkdb'
os.environ['DB_PORT'] = '28015'
os.environ['DB_NAME'] = 'ipercron'

我可以编写我的解析器,但我想知道是否有任何现有的模块/工具可以从配置文件中读取环境变量?

8 个答案:

答案 0 :(得分:26)

我使用Python Dotenv Library。只需安装库pip install python-dotenv,用您的环境变量创建一个.env文件,然后将环境变量导入代码中,如下所示:

import os
from dotenv import load_dotenv

load_dotenv()

MY_ENV_VAR = os.getenv('MY_ENV_VAR')

来自.env文件:

MY_ENV_VAR="This is my env var content."

当我需要在docker系统之外测试代码并准备将其再次返回docker时,这就是我要做的事情。

答案 1 :(得分:21)

答案 2 :(得分:7)

您可以使用ConfigParser。可以找到示例示例here

但是此库希望您的key = value数据存在于某些[heading]下。例如,像:

[mysqld]
user = mysql  # Key with values
pid-file = /var/run/mysqld/mysqld.pid
skip-external-locking
old_passwords = 1
skip-bdb      # Key without value
skip-innodb

答案 3 :(得分:6)

如果您的系统/环境/工作流支持 POSIX shell 脚本,您可以创建一个包含这两个操作的脚本:

  1. Sourcing the .env file and exporting them as environment variables
    • 使用 set -a 选项,其中“创建或修改的每个变量或函数都被赋予导出属性并标记为导出到后续命令的环境”。
  2. 调用具有普通 os.environ.get 代码的 Python 脚本/应用

这是一个示例 .env 文件 (config.env):

TYPE=prod
PORT=5000

这是 Python 代码 (test.py):

import os

print(os.environ.get('TYPE'))
print(os.environ.get('PORT'))

这是一个示例 bash 脚本 (run.sh):

#!/usr/local/bin/bash

set -a
source config.env
set +a

python3 test.py

这是一个示例运行:

$ tree
.
├── config.env
├── run.sh
└── test.py

$ echo $TYPE

$ echo $PORT

$ python3 test.py
None
None

$ ./run.sh 
prod
5000

当您直接运行 Python 脚本 (python3 test.py) 时,它使用 .environ.get 而没有 source-ing .env 文件,它都会打印出 None。< /p>

但是,当您将其包装在首先将 .env 文件加载到环境变量中的 shell 脚本中,然后运行 ​​Python 脚本(仍然使用 .environ.get)时,Python 脚本现在应该能够读取环境变量没问题。

other popular answer 相比,它不需要任何外部 Python 库。

答案 4 :(得分:4)

如何获得更紧凑的解决方案:

import os

with open('.docker-compose-env', 'r') as fh:
    vars_dict = dict(
        tuple(line.split('='))
        for line in fh.readlines() if not line.startswith('#')
    )

print(vars_dict)
os.environ.update(vars_dict)

答案 5 :(得分:3)

这也可能对您有用:

env_vars = []
with open(env_file) as f:
    for line in f:
        if line.startswith('#'):
            continue
        # if 'export' not in line:
        #     continue
        # Remove leading `export `, if you have those
        # then, split name / value pair
        # key, value = line.replace('export ', '', 1).strip().split('=', 1)
        key, value = line.strip().split('=', 1)
        # os.environ[key] = value  # Load to local environ
        env_vars.append({'name': key, 'value': value}) # Save to a list

print(env_vars);

在注释中,您会找到几种保存env var的不同方法,以及一些解析选项,即摆脱了前导export关键字。另一种方法是使用python-dotenv库。干杯。

答案 6 :(得分:0)

我所知的加载环境变量的最佳实践如下。

创建一个constants.py文件。

env_variable_one = 'env_variable_one'
env_variable_two = 'env_variable_two'

然后按如下所示将变量加载到main.py中。

from os import environ as env
from dotenv import load_dotenv, find_dotenv
import constants

ENV_FILE = find_dotenv()
if ENV_FILE:
    load_dotenv(ENV_FILE)

env_variable_one = env.get(constants.env_variable_one)
env_variable_two = env.get(constants.env_variable_two)

编辑:

请参考此存储库-https://github.com/auth0-samples/auth0-python-web-app/tree/master/01-Login,该存储库具有遵循python和处理行业安全性的最佳实践之一的工作代码。

答案 7 :(得分:0)

Dewald Abrie发布了一个很好的解决方案,这是一个略微的修改,忽略了换行符(\ n)

def get_env_data_as_dict(path: str) -> dict:
    with open(path, 'r') as f:
       return dict(tuple(line.replace('\n', '').split('=')) for line
                in f.readlines() if not line.startswith('#'))

print(get_env_data_as_dict('../db.env'))