跳转到主要内容

Python类型化环境变量解析

项目描述

Build Status codecov.io PyPI version

typenv

版本 0.2.0

Python类型化环境变量解析

目录 mdformat-toc 生成

背景

Typenv使用与优秀的environs几乎相同的API进行环境变量解析。以下是选择typenv的一些原因

  • 类型注解的类型转换函数:类型检查器可以理解解析的环境变量的类型。
  • 更灵活的环境变量名称前缀操作。
  • 环境变量名称验证。
  • 可选的自动将环境变量名称大写。
  • 能够生成一个显示环境变量预期类型的 .env.example 文件。
  • 更少的依赖。不需要 marshmallow

安装

从PyPI仓库安装 (https://pypi.ac.cn/project/typenv)

pip install typenv

用法

基础知识

设置环境变量

export NAME='Harry Potter'
export AGE=14
export IS_WIZARD=true
export PATRONUM_SUCCESS_RATE=0.92
export BANK_BALANCE=134599.01
export LUCKY_NUMBERS=7,3,11
export EXTRA_DETAILS='{"friends": ["Hermione", "Ron"]}'
export FAVORITE_COLOR=0x7f0909

在Python中解析值

from typenv import Env

env = Env()

NAME = env.str("NAME")  # => "Harry Potter"
AGE = env.int("AGE")  # => 14
IS_WIZARD = env.bool("IS_WIZARD")  # => True
PATRONUM_SUCCESS_RATE = env.float("PATRONUM_SUCCESS_RATE")  # => 0.92
BANK_BALANCE = env.decimal("BANK_BALANCE")  # => decimal.Decimal("134599.01")
LUCKY_NUMBERS = env.list("LUCKY_NUMBERS", subcast=int)  # => [7, 3, 11]
EXTRA_DETAILS = env.json("EXTRA_DETAILS")  # => {"friends": ["Hermione", "Ron"]}
FAVORITE_COLOR = env.bytes("FAVORITE_COLOR", encoding="hex")  # => b"\x7f\t\t"

# Optional settings must have a default value
IS_DEATH_EATER = env.bool("IS_DEATH_EATER", default=False)  # => False

支持类型

typenv支持以下类型

  • env.str
  • env.int
  • env.bool
  • env.float
  • env.decimal
  • env.list
    • 接受一个subcast关键字参数,用于将列表项转换为strintboolfloatdecimal.Decimal之一
  • env.json
  • env.bytes
    • 接受一个encoding关键字参数来指示字节编码方式。目前只支持hex

默认值

通常情况下,如果未找到环境变量,typenv会抛出异常。但是,如果提供了默认值,则将返回该值而不是抛出异常。

from typenv import Env

env = Env()

BOOL = env.bool("NON_EXISTING_NAME", default=False)  # => False
LIST = env.list("NON_EXISTING_NAME", default=["a", "b"])  # => ["a", "b"]
OPTIONAL_INT = env.int("NON_EXISTING_NAME", default=None)  # => None

名称前缀

export FLASK_HOST=127.0.0.1
export FLASK_PORT=44144
from typenv import Env

env = Env()

# Explicitly prefixing variable names works, but repeats itself
# (especially given more environment variables and nested prefixes).
HOST = env.str("FLASK_HOST")  # => "127.0.0.1"
PORT = env.int("FLASK_PORT")  # => 44144

# This reads the same variables as above, and can be a nice way of
# reducing repetition and expressing structure. Note that it is possible
# to have nested `with` statements.
with env.prefixed("FLASK_"):
    HOST = env.str("HOST")  # => "127.0.0.1"
    PORT = env.int("PORT")  # => 44144

# For more control, one can mutate `env.prefix` (of type list[str])
# directly. Note that if an exception occurs reading the environment
# variables, then `env.prefix` will not be reset to its initial value,
# which is something that the `with` statement would take care of.
env.prefix.append("FLASK_")
HOST = env.str("HOST")  # => "127.0.0.1"
PORT = env.int("PORT")  # => 44144
env.prefix.pop()

名称字符集

Typenv验证环境变量名称。默认情况下,允许的字符集包括大写ASCII字母、数字和下划线(_)。

允许的字符集可以配置

from typenv import Env

env = Env(allowed_chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ")

名称大写化

export UPPER_CASE_NAME=true
from typenv import Env

# Environment variable names in type cast methods will automatically be upper
# cased when `upper=True` is set here.
env = Env(upper=True)

NAME = env.bool("upper_casE_Name")

验证

export NAME='Harry Potter'
export AGE=14
from typenv import Env

env = Env()

# A single validator function
NAME = env.str("NAME", validate=lambda n: n.startswith("Harry"))

# A validator function can signal error by raising an exception
def is_positive(num):
    if num <= 0:
        raise Exception("Number is not positive")


# A validator function can alternatively return `False` to signal an error
def is_less_than_thousand(num):
    if num >= 1000:
        return False
    return True


# Multiple validator functions can be passed as an iterable of callables
AGE = env.int("AGE", validate=(is_positive, is_less_than_thousand))

.env文件读取

在开发过程中,从文件中读取环境变量通常很有用。Typenv通过Env.read_end()方法支持此功能。该方法将在当前工作目录中查找名为.env的文件(默认情况)。它会从该文件中导入环境变量。如果没有找到文件,该方法将遍历目录树直到找到文件或到达根目录。该方法返回一个布尔值,如果找到文件则返回True

当前工作目录中有一个名为.env的文件,其内容如下

SOME_VAR='some value'

以下代码将能够读取并解析值

from typenv import Env

env = Env()
env.read_env()

SOME_VAR = env.str("SOME_VAR")  # => "some value"

导出解析的值

export SOME_STR=blaablaa
export SOME_INT=99
from typenv import Env, ParsedValue

env = Env()

SOME_STR = env.str("SOME_STR")
SOME_INT = env.int("SOME_INT")

assert env.dump() == {
    "SOME_INT": ParsedValue(value=99, type="int", optional=False),
    "SOME_STR": ParsedValue(value="blaablaa", type="str", optional=False),
}

致谢

此库的公共API几乎是environs的一个精确副本,environs基于envparsedjango-environ。接口的功劳归功于这些库的作者。

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分布

typenv-0.2.0.tar.gz (10.0 kB 查看哈希)

上传时间

构建分布

typenv-0.2.0-py3-none-any.whl (8.3 kB 查看哈希)

上传时间 Python 3

由以下支持