我想在本地环境中运行一个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'

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


当前回答

如果你的系统/环境/工作流支持使用shell脚本,你可以创建一个脚本来包装这两个操作:

获取.env文件并将其导出为环境变量 使用set -a选项,其中“每个创建或修改的变量或函数都被赋予export属性,并标记为导出到后续命令的环境”。 调用具有简单os. environment .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/bin/env 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)而不获取.env文件时,所有的environ。get calls返回None。

但是,当您将它包装在一个shell脚本中,该脚本首先将.env文件加载到环境变量中,然后再运行Python脚本时,Python脚本现在应该能够正确地读取环境变量。它还确保导出的env变量仅作为Python应用程序/脚本执行的一部分存在。

与其他流行的答案相比,这不需要任何外部Python库。

其他回答

如果你的系统/环境/工作流支持使用shell脚本,你可以创建一个脚本来包装这两个操作:

获取.env文件并将其导出为环境变量 使用set -a选项,其中“每个创建或修改的变量或函数都被赋予export属性,并标记为导出到后续命令的环境”。 调用具有简单os. environment .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/bin/env 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)而不获取.env文件时,所有的environ。get calls返回None。

但是,当您将它包装在一个shell脚本中,该脚本首先将.env文件加载到环境变量中,然后再运行Python脚本时,Python脚本现在应该能够正确地读取环境变量。它还确保导出的env变量仅作为Python应用程序/脚本执行的一部分存在。

与其他流行的答案相比,这不需要任何外部Python库。

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'))

我认为您应该把它留给外部工具来为您管理环境。

这样,您就可以轻松地使用像1password cli这样的秘密管理器从加密库中加载环境变量

op run --env-file=.env -- python your_script.py

有了这个load_dotenv足够聪明,如果环境中存在.env变量,而其他一些解决方案则不加载。

如果你没有任何外部工具,可以使用'bash':

set -o allexport; source .env; set +o allexport

方法:从键/值对文件中设置环境变量

我使用Python Dotenv库。只需要安装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时,我就是这样做的。

下面是一个更紧凑的解决方案:

import os

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

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