Skip to main content

Yet another wrapper object for environment variables. Does only the things I care about.

Project description

Author:

Keryn Knight

Version:
0.1.0

A small module for wrapping over environment variables (pulled from os.environ) which provides convenience methods to fetch and check various data types (including iterables) in what I’d charitably hope is a sensible way.

Explicitly doesn’t attempt to read from any .env or .envrc file, because that doesn’t describe valid examples or which things may/should be set into the environment. It becomes an absolute pot-luck.

Tracks requested environment variables and their default/fallback/example values, and whether or not the fallback was used. Never tracks the actual environment value.

If this package isn’t to your liking, there’s plenty of others, and I’m largely suffering from Not-Invented-Here syndrome.

All methods exposed by the Environment accept a key and a default.

  • The key is the environment variable to search for.

  • The default MUST be a string, as it is subject to the same parsing as if it had been found in the environment, and thus serves as a documented example of a valid value to export as an environment variable. Enforced value documentation!

Example usage

A short series of some of the options:

from enviable import env, Environment
# the module level `env` is a premade `Environment` to work with and is
# roughly the same as `myenv = Environment(os.environ)`

DEBUG = env.bool("DEBUG", "off")
GIT_HASH = env.hex("COMMIT_REF", "11ff3fe8ccfa4bbd9c144f68b84c80f6")
SERVER_EMAIL = env.email("DEFAULT_EMAIL", "a@b.com")
DYANMIC_IMPORT = env.importable("MY_MODULE", "path.to.mymodule")
LOCAL_FILE = env.filepath("ACCESS_KEYS", "/valid/path/to/keys.json")
API_URL = env.web_address("API_URL", "https://example.com/")

# Iterables
NUMBERS = env.tuple("NUMBERS", "(12,3,456)", converter=env.ensure.int)
UNORDERED_NUMBERS = env.frozenset("NUMBERS", "12, 3, 456", converter=env.ensure.int)
DICTISH = env.dict("WOO", "a=1, b=2, c=3", key_converter=env.ensure.text, value_converter=env.ensure.int)

# Raw text *followed* by conversion
DEEPER_DEBUG = env.ensure.bool(env.text("DEBUG_DEEPLY", "1"))

Handling errors

Failing to successfully convert (or just validate) the value (whether from the environment or from the fallback) immediately halts execution by raising EnvironmentCastError which is a subclass of ValueError - it is recommended that you only catch the former.

Types

Should be able to handle the following:

  • text

  • integer

  • boolean

  • uuid (with and without hyphens)

  • email (checks the string is email-like. Does not fully parse/validate, because that’s a fool’s errand)

  • hex (validates the string)

  • base64 encoded data (validates it decodes)

  • decimal

  • importable python paths (validates the string)

  • file paths (validates the file exists and is readable)

  • directories (validates the directory exists)

  • URLs (sanity-checks the string … ish)

  • tuples/lists/sets/frozensets of any of the above

  • dictionaries, with separate key & value conversion

  • json

If Django is installed (sorry, I’m lazy) it should also handle:

  • datetime

  • date

  • time

Casting on iterables

Using any of env.tuple, env.list, env.set, env.frozenset, or env.dict allows each parsed value to be validated and optionally cast, with the caveat that the iterable is homogenous (that is, everything can be converted to an int or a uuid or whatever)

env.dict is slightly special in that it has arguments for key_converter and value_converter so that keys can have a different type to values. Both must still be homogenous.

Running the tests

Given a copy of the file enviable.py you ought to be able to do:

python enviable.py

and see the output of the various tests I’ve bothered with.

TODO

  • Examples of every type / method

  • More tests

The license

It’s FreeBSD. There’s should be a LICENSE file in the root of the repository, and in any archives.


Copyright (c) 2019, Keryn Knight All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Change history for enviable

?next?

0.1.0

  • Initial export

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

enviable-0.1.0.tar.gz (14.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

enviable-0.1.0-py2.py3-none-any.whl (12.0 kB view details)

Uploaded Python 2Python 3

File details

Details for the file enviable-0.1.0.tar.gz.

File metadata

  • Download URL: enviable-0.1.0.tar.gz
  • Upload date:
  • Size: 14.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/42.0.2 requests-toolbelt/0.9.1 tqdm/4.40.2 CPython/3.6.8

File hashes

Hashes for enviable-0.1.0.tar.gz
Algorithm Hash digest
SHA256 48bfd7b0eeecf4713065d3b355247ff846e14f7f15f187f6034fcb96465964eb
MD5 ca97a0538657bfaae235b459c5cfdd24
BLAKE2b-256 d9a6aa856c6591baf133c6f74d0a9e64b2338a15a11cc84081f2cfdec690dec7

See more details on using hashes here.

File details

Details for the file enviable-0.1.0-py2.py3-none-any.whl.

File metadata

  • Download URL: enviable-0.1.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 12.0 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/42.0.2 requests-toolbelt/0.9.1 tqdm/4.40.2 CPython/3.6.8

File hashes

Hashes for enviable-0.1.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 2d938b1a9cd88297a5efe7251e4aafe0bc4ab68656ae5fb36c4ff16020b57786
MD5 5acaa68d9dade0731b8acab707dafab0
BLAKE2b-256 b018376c726d0729e7932fc9abe985686a764a8e6bf9206365305ff82cfc1e38

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page