Environs是解析环境变量的python库。它的开发受 envparse 启发,底层使用 marshmallow 验证并序列化值。
安装
pip install environs
基本使用
# export GITHUB_USER=sloria# export API_KEY=123abc
# export SHIP_DATE='1984-06-25'
# export ENABLE_LOGIN=true
# export GITHUB_REPOS=webargs,konch,ped
# export COORDINATES=23.3,50.0
from environs import Env
env = Env()
# reading an environment variable
gh_user = env('GITHUB_USER') # => 'sloria'
secret = env('SECRET') # => raises error if not set
# cast
ingapi_key = env.str('API_KEY') # => '123abc'
date = env.date('SHIP_DATE') # => datetime.date(1984, 6, 25)
# providing a default value
enable_login = env.bool('ENABLE_LOGIN', False) # => True
enable_feature_x = env.bool('ENABLE_FEATURE_X', False) # => False
# parsing lists
gh_repos = env.list('GITHUB_REPOS') # => ['webargs', 'konch', 'ped']
coords = env.list('COORDINATES', subcast=float) # => [23.3, 50.0]
支持的类型
下面是Env类型转换的方法:
env.str
env.bool
env.int
env.float
env.decimal
env.list (accepts optional subcast keyword argument)
env.dict (accepts optional subcast keyword argument)
env.json
env.datetime
env.date
env.timedelta (assumes value is an integer in seconds)
env.uuid
处理前缀
# export MYAPP_HOST=lolcathost# export MYAPP_PORT=3000
with env.prefixed('MYAPP_'):
host = env('HOST', 'localhost') # => 'lolcathost'
port = env.int('PORT', 5000) # => 3000
代理变量
# export MAILGUN_LOGIN=sloria# export SMTP_LOGIN={{MAILGUN_LOGIN}}
smtp_login = env('SMTP_LOGIN') # =>'sloria'
验证
# export TTL=-2# export NODE_ENV='invalid'
# export EMAIL='^_^'
# simple validator
env.int('TTL', validate=lambda n: n > 0)
# => Environment variable "TTL" invalid: ['Invalid value.']
# using marshmallow validators
from marshmallow.validate import OneOf
env.str('NODE_ENV',
validate=OneOf(['production', 'development'],
error='NODE_ENV must be one of: {choices}'))
# => Environment variable "NODE_ENV" invalid: ['NODE_ENV must be one of: production, development']
# multiple validators
from marshmallow.validate import Length, Email
env.str('EMAIL', validate=[Length(min=4), Email()])
# => Environment variable "EMAIL" invalid: ['Shorter than minimum length 4.', 'Not a valid email address.']
序列化
# serialize to a dictionary of simple types (numbers and strings)env.dump()
# { 'API_KEY': '123abc',
# 'COORDINATES': [23.3, 50.0],
# 'ENABLE_FEATURE_X': False,
# 'ENABLE_LOGIN': True,
# 'GITHUB_REPOS': ['webargs', 'konch', 'ped'],
# 'GITHUB_USER': 'sloria',
# 'MYAPP_HOST': 'lolcathost',
# 'MYAPP_PORT': 3000,
# 'SHIP_DATE': '1984-06-25'}
定义自定义的解析行为
# export DOMAIN='http://myapp.com'# export COLOR=invalid
from furl import furl
# Register a new parser method for paths
@env.parser_for('furl')
def furl_parser(value):
return furl(value)
domain = env.furl('DOMAIN') # => furl('https://myapp.com')
# Custom parsers can take extra keyword arguments
@env.parser_for('enum')
def enum_parser(value, choices):
if value not in choices:
raise environs.EnvError('Invalid!')
return value
color = env.enum('COLOR', choices=['black']) # => raises EnvError
注意:被自定义的解析函数解析过的环境变量,会被不做任何修改地 传递给Env.dump 序列化。要定义特殊的序列化行为,请使用 Env.parser_from_field (看下一章)。
Marshmallow集成 # export STATIC_PATH='app/static'# Custom parsers can be defined as marshmallow Fields
import pathlib
import marshmallow as ma
class PathField(ma.fields.Field):
def _deserialize(self, value, *args, **kwargs):
return pathlib.Path(value)
def _serialize(self, value, *args, **kwargs):
return str(value)
env.add_parser_from_field('path', PathField)
static_path = env.path('STATIC_PATH') # => PosixPath('app/static')
env.dump()['STATIC_PATH'] # => 'app/static'
读 .env文件
使用外部的read_env包将.env文件读入os.environ
pip install read_env
# myapp/.envDEBUG=true
PORT=4567
解析变量之前调用 read_env 。
from environs import Envfrom read_env import read_env
env = Env()
# Read .env into os.environ
read_env()
env.bool('DEBUG') # => True
env.int('PORT') # => 4567
为什么?
为什么用envvars?参见:http://12factor.net/config
为什么不用os.environ?os.environ在简单场合确实已经够用了。一些典型应用需要需要方法去管理和验证原始的环境变量。Environs抽象处理环境变量的常用任务。
Environs会帮你:
转化 envvars 到正确的类型
指定需要的envvars
定义默认值
验证envvars
解析列表和字典值
解析日期,时间和时间差
解析代理变量
把你的配置序列化为JSON, YAML, 等等.
为什么额外使用一个库?已经有了很多解析环境变量的很好的库。事实上,Environs大多数的API都是由envparse和django-environ的作者定的。
environs主要要实现三个目标:
让扩展解析行为和编写插件变的容易。
把序列化和验证的工作交给marshmallow去做。
清除冗余的API.
英文原文及项目地址
https://github.com/sloria/environs