environs


Nameenvirons JSON
Version 2.1.0 PyPI version JSON
download
home_pagehttps://github.com/sloria/environs
Summarysimplified environment variable parsing
upload_time2018-01-25 05:04:40
maintainer
docs_urlNone
authorSteven Loria
requires_python
licenseMIT
keywords environment variables parsing
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI
coveralls test coverage No coveralls.
            *************************************************
environs: simplified environment variable parsing
*************************************************

.. image:: https://badge.fury.io/py/environs.svg
    :target: http://badge.fury.io/py/environs
    :alt: Latest version

.. image:: https://travis-ci.org/sloria/environs.svg?branch=master
    :target: https://travis-ci.org/sloria/environs
    :alt: Travis-CI


Environs is a Python library for parsing environment variables.

Environs is inspired by `envparse <https://github.com/rconradharris/envparse>`_ and uses `marshmallow <https://github.com/marshmallow-code/marshmallow>`_ under the hood for validating, deserializing, and serializing values.

Install
-------
::

    pip install environs

Basic usage
-----------

.. code-block:: python

    # export GITHUB_USER=sloria
    # export MAX_CONNECTIONS=100
    # export SHIP_DATE='1984-06-25'
    # export TTL=42
    # export ENABLE_LOGIN=true
    # export GITHUB_REPOS=webargs,konch,ped
    # export COORDINATES=23.3,50.0

    from environs import Env

    env = Env()
    # required variables
    gh_user = env('GITHUB_USER')  # => 'sloria'
    secret = env('SECRET')  # => raises error if not set

    # casting
    max_connections = env.int('MAX_CONNECTIONS')  # => 100
    ship_date = env.date('SHIP_DATE')  # => datetime.date(1984, 6, 25)
    ttl = env.timedelta('TTL')  # => datetime.timedelta(0, 42)

    # 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]


Supported types
---------------

The following are all type-casting methods of  ``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.url``
* ``env.uuid``


Handling prefixes
-----------------

.. code-block:: python

    # export MYAPP_HOST=lolcathost
    # export MYAPP_PORT=3000

    with env.prefixed('MYAPP_'):
        host = env('HOST', 'localhost')  # => 'lolcathost'
        port = env.int('PORT', 5000)  # => 3000

    # nested prefixes are also supported:

    # export MYAPP_DB_HOST=lolcathost
    # export MYAPP_DB_PORT=10101

    with env.prefixed('MYAPP_'):
        with env.prefixed('DB_'):
            db_host = env('HOST', 'lolcathost')
            db_port = env.int('PORT', 10101)


Proxied variables
-----------------

.. code-block:: python

    # export MAILGUN_LOGIN=sloria
    # export SMTP_LOGIN={{MAILGUN_LOGIN}}

    smtp_login = env('SMTP_LOGIN')  # =>'sloria'


Validation
----------

.. code-block:: python

    # 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.']


Serialization
-------------

.. code-block:: python

    # serialize to a dictionary of simple types (numbers and strings)
    env.dump()
    # {'COORDINATES': [23.3, 50.0],
    # 'ENABLE_FEATURE_X': False,
    # 'ENABLE_LOGIN': True,
    # 'GITHUB_REPOS': ['webargs', 'konch', 'ped'],
    # 'GITHUB_USER': 'sloria',
    # 'MAX_CONNECTIONS': 100,
    # 'MYAPP_HOST': 'lolcathost',
    # 'MYAPP_PORT': 3000,
    # 'SHIP_DATE': '1984-06-25',
    # 'TTL': 42}

Defining custom parser behavior
-------------------------------

.. code-block:: python

    # 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

Note: Environment variables parsed with a custom parser function will be serialized by ``Env.dump`` without any modification. To define special serialization behavior, use ``Env.parser_from_field`` instead (see next section).

Marshmallow integration
-----------------------

.. code-block:: python

    # 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'

Reading ``.env`` files
----------------------

.. code-block:: bash

    # myapp/.env
    DEBUG=true
    PORT=4567

Call ``Env.read_env`` before parsing variables.

.. code-block:: python

    from environs import Env

    env = Env()
    # Read .env into os.environ
    env.read_env()

    env.bool('DEBUG')  # => True
    env.int('PORT')   # => 4567

Why...?
-------

Why envvars?
++++++++++++

See `The 12-factor App <http://12factor.net/config>`_ section on `configuration <http://12factor.net/config>`_.

Why not ``os.environ``?
+++++++++++++++++++++++

While ``os.environ`` is enough for simple use cases, a typical application will need a way to manipulate and validate raw environment variables. Environs abstracts common tasks for handling environment variables.

Environs will help you

* cast envvars to the correct type
* specify required envvars
* define default values
* validate envvars
* parse list and dict values
* parse dates, datetimes, and timedeltas
* parse proxied variables
* serialize your configuration to JSON, YAML, etc.

Why another library?
++++++++++++++++++++

There are many great Python libraries for parsing environment variables. In fact, most of the credit for environs' public API goes to the authors of `envparse <https://github.com/rconradharris/envparse>`_ and `django-environ <https://github.com/joke2k/django-environ>`_.

environs aims to meet three additional goals:

1. Make it easy to extend parsing behavior and develop plugins.
2. Leverage the deserialization and validation functionality provided by a separate library (marshmallow).
3. Clean up redundant API.


License
-------

MIT licensed. See the `LICENSE <https://github.com/sloria/environs/blob/master/LICENSE>`_ file for more details.



*********
Changelog
*********

2.1.0 (2018-01-25)
------------------

Features:

* Add `recurse` parameter to `Env.read_env` (`#9 <https://github.com/sloria/environs/pull/9>`_).
  Thanks `gthank <https://github.com/gthank>`_ for the PR.

2.0.0 (2018-01-02)
------------------

Features:

* Add support for nested prefixes (`#8 <https://github.com/sloria/environs/pull/8>`_).
  Thanks `gvialetto <https://github.com/gvialetto>`_ for the PR.

Other changes:

* *Backwards-incompatible*: Drop support for Python 3.3 and 3.4.

1.2.0 (2017-01-12)
------------------

Features:

* Add ``url`` parser that returns a ``urllib.parse.ParseResult`` (`#6 <https://github.com/sloria/environs/issues/6>`_). Thanks `IlyaSemenov <https://github.com/IlyaSemenov>`_ for the suggestion.

Bug fixes:

* Every instance of ``Env`` gets its own parser map, so calling ``env.parser_for`` for one instance doesn't affect other instances.

1.1.0 (2016-05-01)
------------------

* Add ``Env.read_env`` method for reading ``.env`` files.

1.0.0 (2016-04-30)
------------------

* Support for proxied variables (`#2 <https://github.com/sloria/environs/issues/2>`_).
* *Backwards-incompatible*: Remove ``env.get`` method. Use ``env()`` instead.
* Document how to read ``.env`` files (`#1 <https://github.com/sloria/environs/issues/1>`_).

0.1.0 (2016-04-25)
------------------

* First PyPI release.



            

Raw data

            {
    "maintainer": "", 
    "docs_url": null, 
    "requires_python": "", 
    "maintainer_email": "", 
    "cheesecake_code_kwalitee_id": null, 
    "keywords": "environment variables parsing", 
    "upload_time": "2018-01-25 05:04:40", 
    "author": "Steven Loria", 
    "home_page": "https://github.com/sloria/environs", 
    "github_user": "sloria", 
    "download_url": "https://pypi.python.org/packages/02/9a/a0dfc5165d4a6b71ad9b3c9b7038c49f3c4f7c6524a4d73f251148ea8083/environs-2.1.0.tar.gz", 
    "platform": "", 
    "version": "2.1.0", 
    "cheesecake_documentation_id": null, 
    "description": "*************************************************\nenvirons: simplified environment variable parsing\n*************************************************\n\n.. image:: https://badge.fury.io/py/environs.svg\n    :target: http://badge.fury.io/py/environs\n    :alt: Latest version\n\n.. image:: https://travis-ci.org/sloria/environs.svg?branch=master\n    :target: https://travis-ci.org/sloria/environs\n    :alt: Travis-CI\n\n\nEnvirons is a Python library for parsing environment variables.\n\nEnvirons is inspired by `envparse <https://github.com/rconradharris/envparse>`_ and uses `marshmallow <https://github.com/marshmallow-code/marshmallow>`_ under the hood for validating, deserializing, and serializing values.\n\nInstall\n-------\n::\n\n    pip install environs\n\nBasic usage\n-----------\n\n.. code-block:: python\n\n    # export GITHUB_USER=sloria\n    # export MAX_CONNECTIONS=100\n    # export SHIP_DATE='1984-06-25'\n    # export TTL=42\n    # export ENABLE_LOGIN=true\n    # export GITHUB_REPOS=webargs,konch,ped\n    # export COORDINATES=23.3,50.0\n\n    from environs import Env\n\n    env = Env()\n    # required variables\n    gh_user = env('GITHUB_USER')  # => 'sloria'\n    secret = env('SECRET')  # => raises error if not set\n\n    # casting\n    max_connections = env.int('MAX_CONNECTIONS')  # => 100\n    ship_date = env.date('SHIP_DATE')  # => datetime.date(1984, 6, 25)\n    ttl = env.timedelta('TTL')  # => datetime.timedelta(0, 42)\n\n    # providing a default value\n    enable_login = env.bool('ENABLE_LOGIN', False)  # => True\n    enable_feature_x = env.bool('ENABLE_FEATURE_X', False)  # => False\n\n    # parsing lists\n    gh_repos = env.list('GITHUB_REPOS')  # => ['webargs', 'konch', 'ped']\n    coords = env.list('COORDINATES', subcast=float)  # => [23.3, 50.0]\n\n\nSupported types\n---------------\n\nThe following are all type-casting methods of  ``Env``:\n\n* ``env.str``\n* ``env.bool``\n* ``env.int``\n* ``env.float``\n* ``env.decimal``\n* ``env.list`` (accepts optional ``subcast`` keyword argument)\n* ``env.dict`` (accepts optional ``subcast`` keyword argument)\n* ``env.json``\n* ``env.datetime``\n* ``env.date``\n* ``env.timedelta`` (assumes value is an integer in seconds)\n* ``env.url``\n* ``env.uuid``\n\n\nHandling prefixes\n-----------------\n\n.. code-block:: python\n\n    # export MYAPP_HOST=lolcathost\n    # export MYAPP_PORT=3000\n\n    with env.prefixed('MYAPP_'):\n        host = env('HOST', 'localhost')  # => 'lolcathost'\n        port = env.int('PORT', 5000)  # => 3000\n\n    # nested prefixes are also supported:\n\n    # export MYAPP_DB_HOST=lolcathost\n    # export MYAPP_DB_PORT=10101\n\n    with env.prefixed('MYAPP_'):\n        with env.prefixed('DB_'):\n            db_host = env('HOST', 'lolcathost')\n            db_port = env.int('PORT', 10101)\n\n\nProxied variables\n-----------------\n\n.. code-block:: python\n\n    # export MAILGUN_LOGIN=sloria\n    # export SMTP_LOGIN={{MAILGUN_LOGIN}}\n\n    smtp_login = env('SMTP_LOGIN')  # =>'sloria'\n\n\nValidation\n----------\n\n.. code-block:: python\n\n    # export TTL=-2\n    # export NODE_ENV='invalid'\n    # export EMAIL='^_^'\n\n\n    # simple validator\n    env.int('TTL', validate=lambda n: n > 0)\n    # => Environment variable \"TTL\" invalid: ['Invalid value.']\n\n    # using marshmallow validators\n    from marshmallow.validate import OneOf\n\n    env.str('NODE_ENV',\n            validate=OneOf(['production', 'development'],\n                            error='NODE_ENV must be one of: {choices}'))\n    # => Environment variable \"NODE_ENV\" invalid: ['NODE_ENV must be one of: production, development']\n\n    # multiple validators\n    from marshmallow.validate import Length, Email\n\n    env.str('EMAIL', validate=[Length(min=4), Email()])\n    # => Environment variable \"EMAIL\" invalid: ['Shorter than minimum length 4.', 'Not a valid email address.']\n\n\nSerialization\n-------------\n\n.. code-block:: python\n\n    # serialize to a dictionary of simple types (numbers and strings)\n    env.dump()\n    # {'COORDINATES': [23.3, 50.0],\n    # 'ENABLE_FEATURE_X': False,\n    # 'ENABLE_LOGIN': True,\n    # 'GITHUB_REPOS': ['webargs', 'konch', 'ped'],\n    # 'GITHUB_USER': 'sloria',\n    # 'MAX_CONNECTIONS': 100,\n    # 'MYAPP_HOST': 'lolcathost',\n    # 'MYAPP_PORT': 3000,\n    # 'SHIP_DATE': '1984-06-25',\n    # 'TTL': 42}\n\nDefining custom parser behavior\n-------------------------------\n\n.. code-block:: python\n\n    # export DOMAIN='http://myapp.com'\n    # export COLOR=invalid\n\n    from furl import furl\n\n    # Register a new parser method for paths\n    @env.parser_for('furl')\n    def furl_parser(value):\n        return furl(value)\n\n    domain = env.furl('DOMAIN')  # => furl('https://myapp.com')\n\n\n    # Custom parsers can take extra keyword arguments\n    @env.parser_for('enum')\n    def enum_parser(value, choices):\n        if value not in choices:\n            raise environs.EnvError('Invalid!')\n        return value\n\n    color = env.enum('COLOR', choices=['black'])  # => raises EnvError\n\nNote: Environment variables parsed with a custom parser function will be serialized by ``Env.dump`` without any modification. To define special serialization behavior, use ``Env.parser_from_field`` instead (see next section).\n\nMarshmallow integration\n-----------------------\n\n.. code-block:: python\n\n    # export STATIC_PATH='app/static'\n\n    # Custom parsers can be defined as marshmallow Fields\n    import pathlib\n\n    import marshmallow as ma\n\n    class PathField(ma.fields.Field):\n        def _deserialize(self, value, *args, **kwargs):\n            return pathlib.Path(value)\n\n        def _serialize(self, value, *args, **kwargs):\n            return str(value)\n\n    env.add_parser_from_field('path', PathField)\n\n    static_path = env.path('STATIC_PATH')  # => PosixPath('app/static')\n    env.dump()['STATIC_PATH']  # => 'app/static'\n\nReading ``.env`` files\n----------------------\n\n.. code-block:: bash\n\n    # myapp/.env\n    DEBUG=true\n    PORT=4567\n\nCall ``Env.read_env`` before parsing variables.\n\n.. code-block:: python\n\n    from environs import Env\n\n    env = Env()\n    # Read .env into os.environ\n    env.read_env()\n\n    env.bool('DEBUG')  # => True\n    env.int('PORT')   # => 4567\n\nWhy...?\n-------\n\nWhy envvars?\n++++++++++++\n\nSee `The 12-factor App <http://12factor.net/config>`_ section on `configuration <http://12factor.net/config>`_.\n\nWhy not ``os.environ``?\n+++++++++++++++++++++++\n\nWhile ``os.environ`` is enough for simple use cases, a typical application will need a way to manipulate and validate raw environment variables. Environs abstracts common tasks for handling environment variables.\n\nEnvirons will help you\n\n* cast envvars to the correct type\n* specify required envvars\n* define default values\n* validate envvars\n* parse list and dict values\n* parse dates, datetimes, and timedeltas\n* parse proxied variables\n* serialize your configuration to JSON, YAML, etc.\n\nWhy another library?\n++++++++++++++++++++\n\nThere are many great Python libraries for parsing environment variables. In fact, most of the credit for environs' public API goes to the authors of `envparse <https://github.com/rconradharris/envparse>`_ and `django-environ <https://github.com/joke2k/django-environ>`_.\n\nenvirons aims to meet three additional goals:\n\n1. Make it easy to extend parsing behavior and develop plugins.\n2. Leverage the deserialization and validation functionality provided by a separate library (marshmallow).\n3. Clean up redundant API.\n\n\nLicense\n-------\n\nMIT licensed. See the `LICENSE <https://github.com/sloria/environs/blob/master/LICENSE>`_ file for more details.\n\n\n\n*********\nChangelog\n*********\n\n2.1.0 (2018-01-25)\n------------------\n\nFeatures:\n\n* Add `recurse` parameter to `Env.read_env` (`#9 <https://github.com/sloria/environs/pull/9>`_).\n  Thanks `gthank <https://github.com/gthank>`_ for the PR.\n\n2.0.0 (2018-01-02)\n------------------\n\nFeatures:\n\n* Add support for nested prefixes (`#8 <https://github.com/sloria/environs/pull/8>`_).\n  Thanks `gvialetto <https://github.com/gvialetto>`_ for the PR.\n\nOther changes:\n\n* *Backwards-incompatible*: Drop support for Python 3.3 and 3.4.\n\n1.2.0 (2017-01-12)\n------------------\n\nFeatures:\n\n* Add ``url`` parser that returns a ``urllib.parse.ParseResult`` (`#6 <https://github.com/sloria/environs/issues/6>`_). Thanks `IlyaSemenov <https://github.com/IlyaSemenov>`_ for the suggestion.\n\nBug fixes:\n\n* Every instance of ``Env`` gets its own parser map, so calling ``env.parser_for`` for one instance doesn't affect other instances.\n\n1.1.0 (2016-05-01)\n------------------\n\n* Add ``Env.read_env`` method for reading ``.env`` files.\n\n1.0.0 (2016-04-30)\n------------------\n\n* Support for proxied variables (`#2 <https://github.com/sloria/environs/issues/2>`_).\n* *Backwards-incompatible*: Remove ``env.get`` method. Use ``env()`` instead.\n* Document how to read ``.env`` files (`#1 <https://github.com/sloria/environs/issues/1>`_).\n\n0.1.0 (2016-04-25)\n------------------\n\n* First PyPI release.\n\n\n", 
    "tox": true, 
    "lcname": "environs", 
    "bugtrack_url": null, 
    "github": true, 
    "coveralls": false, 
    "name": "environs", 
    "license": "MIT", 
    "travis_ci": true, 
    "github_project": "environs", 
    "summary": "simplified environment variable parsing", 
    "split_keywords": [
        "environment", 
        "variables", 
        "parsing"
    ], 
    "author_email": "sloria1@gmail.com", 
    "urls": [
        {
            "has_sig": false, 
            "upload_time": "2018-01-25T05:04:39", 
            "comment_text": "", 
            "python_version": "py2.py3", 
            "url": "https://pypi.python.org/packages/81/7b/416b858cf8b201ca67628ae40472c4572ef096615fd0b6c9c903dbabc2bf/environs-2.1.0-py2.py3-none-any.whl", 
            "md5_digest": "16475f9bb60d9a7371852be8841a9571", 
            "downloads": 0, 
            "filename": "environs-2.1.0-py2.py3-none-any.whl", 
            "packagetype": "bdist_wheel", 
            "path": "81/7b/416b858cf8b201ca67628ae40472c4572ef096615fd0b6c9c903dbabc2bf/environs-2.1.0-py2.py3-none-any.whl", 
            "size": 11169
        }, 
        {
            "has_sig": false, 
            "upload_time": "2018-01-25T05:04:40", 
            "comment_text": "", 
            "python_version": "source", 
            "url": "https://pypi.python.org/packages/02/9a/a0dfc5165d4a6b71ad9b3c9b7038c49f3c4f7c6524a4d73f251148ea8083/environs-2.1.0.tar.gz", 
            "md5_digest": "f0a7019637b77f54cfacbad09da7e588", 
            "downloads": 0, 
            "filename": "environs-2.1.0.tar.gz", 
            "packagetype": "sdist", 
            "path": "02/9a/a0dfc5165d4a6b71ad9b3c9b7038c49f3c4f7c6524a4d73f251148ea8083/environs-2.1.0.tar.gz", 
            "size": 9346
        }
    ], 
    "_id": null, 
    "cheesecake_installability_id": null
}