在之前的公众号文章:开发经验:如何正确设置开发环境与生产环境的配置参数中,我提到了把项目的开发环境与生产环境的配置文件分开管理这种方式。
实际上,项目的配置信息,除了用配置文件以外,还可以使用环境变量来进行设置。有一些项目,他们不用配置文件设置敏感信息,因为害怕一不小心就把敏感信息发送到了Github上面。而是把所有敏感信息设置到环境变量里面。代码直接从环境变量读取这些信息。
在Python里面,读取环境变量非常简单:
- import os
- value = os.getenv('变量名')
假设有一个项目,它运行的时候需要连Redis/MongoDB/Kafka/ElasticSearch。配置信息有五六十条。那么,它可能需要设置很多的环境变量,像下面这样:
- export REDIS_HOST=xxx
- export REDIS_PORT=xxx
- export REDIS_PASSWORD=xxx
- export MONGODB_URI=xxxx
- export KAFKA_SERVER=xxx
- ...
这样做的好处显而易见,一旦设置好环境变量以后,每次启动程序只需要直接运行代码就可以了。当你在开发机上面运行,它自动就连开发环境;当你在生产环境来运行,它自动就会连生产环境。
但坏处也很明显,如果你有多个环境,每次重新修改环境变量就非常麻烦。一般来说,生产环境只有一个,但你还有开发环境、测试环境、预发布环境…。其中生产环境的配置参数你是拿不到的,但另外几个环境的参数你是可以拿到的。假设你现在的代码在开发机运行正常,但是放到测试环境就失败了。那么你想在开发机使用测试环境的参数来调试代码。这个时候你就必须一个一个重新设置环境变量,这就非常麻烦。
但好在Python已经有一个用来管理项目环境变量的第三方库python-dotenv[1]。
这个库使用起来非常简单,只需要两行代码加一个文件。
首先,在项目的根目录创建一个文件,叫做.env。使用Windows的同学可能无法做到,因为Windows使用正常方法没有办法创建一个点开头的文件。但是Linux和macOS可以正常创建。例如:
- NAME=kingname
- SALARY=9999999
- ADDRESS=上海
然后,在项目入口文件的顶部,增加两行代码,如下图所示:
- from dotenv import load_dotenv
- load_dotenv()
这样就完成了。你原来读取环境变量的代码不需要做任何修改,直接读取环境变量就可以了,如下图所示:
从图中可以看到,当我们在Shell里面直接执行echo $ 变量名的时候,显示的是空,说明这个环境变量是没有设置的。当我们运行项目代码的时候,python-dotenv会自动读取.env文件,然后在项目里面设置环境变量。
如果仅仅是读文件,那我当然不会特意介绍它。它还有两个更好用的功能。
如果环境变量已经存在,那么会以已经存在的环境变量为准,.env中对应的项自动失效:
也就是说,这个.env文件,你甚至可以直接上传到生产环境。由于生产环境已经设置好了对应的配置参数,所以.env文件里面的内容自动失效。
第二个好用的功能,是.env里面还可以复用同一个变量。例如,我的项目有一个域名会在多个地方用到:
- EMAIL=contact@kingname.info
- ENTRYPOINT=https://kingname.info/api
- REDIS_HOST=redis.kingname.info
- KAFKA_SERVER=kafka.kingname.info
- ...
如果有一天我要修改这个域名,那么所有配置都需要修改。但是.env可以复用变量:
- DOMAIN=kingname.info
- EMAIL=contact@${DOMAIN}
- ENTRYPOINT=https://${DOMAIN}/api
- REDIS_HOST=redis.${DOMAIN}
- KAFKA_SERVER=kafka.${DOMAIN}
这样一来,当我要改域名的时候,只需要修改DOMAIN的值就可以了。
关于python-dotenv的更多使用说明,大家可以阅读参考文档里面的Readme。
参考文献
[1]python-dotenv: https://github.com/theskumar/python-dotenv