Easily model and convert environment variables you care about.
Class-based modeling of environment variables and their type conversions.
Especially suited to test automation where environment variables are used in abundance, or even in applications that could benefit from these mappings.
For ease of implementation, Python 3.6 is required in order to use PEP-526 variable annotations.
Environment variable access is common, and usually done via a module-based approach.
SERVICE_HOST = os.getenv('COMPANY_APP_HOST') SERVICE_PORT = int(os.getenv('COMPANY_APP_PORT'))
This works just fine, but sometimes they need to be refreshed...
# Whoops, forgot the int conversion! SERVICE_PORT = os.getenv('COMPANY_APP_PORT')
... which isn't very DRY.
Additionally, you may sometimes need to keep track of the name and the value from the environment,
# This is getting verbose quickly ENVNAME_SERVICE_HOST = 'COMPANY_APP_HOST' SERVICE_HOST = os.getenv(ENVNAME_SERVICE_HOST) ENVNAME_SERVICE_PORT = 'COMPANY_APP_PORT' SERVICE_PORT = int(os.getenv(ENVNAME_SERVICE_PORT))
In one swoop, we can map the environment variables as well as their conversions to native types, and fetch either the value or the name:
class ServiceVars(e2e.env.EnvMapper): host: str = 'COMPANY_APP_HOST' port: int = 'COMPANY_APP_PORT' # Get the port via instance print(ServiceVars().port) # 8080 type(ServiceVars().port) # <class 'int'> # Get the name of the port environment variable via class print(ServiceVars.port) # COMPANY_APP_PORT type(ServiceVars.port) # <class 'str'>
Using your own "converters"
EnvMapper does is read the type annotation and constructs the returned
value by passing the environment value to it.
That is, when modeling,
mapped_name: annotated_type = 'ENV_VAR_NAME'
... on access via the
EnvMapper instance, becomes ...
In the above examples for example, we had
port: int = 'COMPANY_APP_PORT'.
This essentially gets shuffled into
any callable that can take a single
str in its constructor and return the
appropriate type will work.
The code is incredibly simple, and will adhere to these contracts:
- Variables that do not exist will cause a
e2e.env.exceptions.NoSuchVariableErrorto be raised.*
- Access of an unmapped environment variable will raise an
AttributeError, as would be reasonably expected.
- Access of a mapping without an annotation will raise a
TypeErrorwith the mapping name and model class.
* Open for discussion. Returning
None could work. Passing
None to the type
converter usually won't produce consistent behaviour across types, and so can't
be determined as a special case (e.g.
Issue #1 for more info.
raise_on_dneor something similar to change what happens when an environment variable is not found. Please add a thumbs-up for Issue #1 if you'd like to see this feature.
class ServiceVars(e2e.env.EnvMapper, raise_on_dne=False): ...
class ServiceVars(e2e.env.EnvMapper, dne=lambda: None): ...
- Support for combining mappings into one larger mapping, for organizational purposes. Please add a thumbs-up for Issue #2 if you'd like to see this feature.
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
|Filename, size||File type||Python version||Upload date||Hashes|
|Filename, size e2e.env-0.1.0-py3-none-any.whl (4.5 kB)||File type Wheel||Python version py3||Upload date||Hashes View|
|Filename, size e2e.env-0.1.0.tar.gz (4.4 kB)||File type Source||Python version None||Upload date||Hashes View|