File: typed_env.rst

package info (click to toggle)
python-plumbum 1.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,300 kB
  • sloc: python: 10,016; makefile: 130; sh: 8
file content (96 lines) | stat: -rw-r--r-- 2,956 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
.. _guide-typed-env:

TypedEnv
========
Plumbum provides this utility class to facilitate working with environment variables.
Similar to how :class:`plumbum.cli.Application` parses command line arguments into pythonic data types,
:class:`plumbum.typed_env.TypedEnv` parses environment variables:

class MyEnv(TypedEnv):
    username = TypedEnv.Str("USER", default='anonymous')
    path = TypedEnv.CSV("PATH", separator=":", type=local.path)
    tmp = TypedEnv.Str(["TMP", "TEMP"])  # support 'fallback' var-names
    is_travis = TypedEnv.Bool("TRAVIS", default=False)  # True is 'yes/true/1' (case-insensitive)

We can now instantiate this class to access its attributes::

    >>> env = MyEnv()
    >>> env.username
    'ofer'

    >>> env.path
    [<LocalPath /home/ofer/bin>,
     <LocalPath /usr/local/bin>,
     <LocalPath /usr/local/sbin>,
     <LocalPath /usr/sbin>,
     <LocalPath /usr/bin>,
     <LocalPath /sbin>,
     <LocalPath /bin>]

    >>> env.tmp
    Traceback (most recent call last):
      [...]
    KeyError: 'TMP'

    >>> env.is_travis
    False

Finally, our ``TypedEnv`` object allows us ad-hoc access to the rest of the environment variables, using dot-notation::

    >>> env.HOME
    '/home/ofer'

We can also update the environment via our ``TypedEnv`` object:

    >>> env.tmp = "/tmp"
    >>> env.tmp
    '/tmp'

    >>> from os import environ
    >>> env.TMP
    '/tmp'

    >>> env.is_travis = True
    >>> env.TRAVIS
    'yes'

    >>> env.path = [local.path("/a"), local.path("/b")]
    >>> env.PATH
    '/a:/b'


TypedEnv as an Abstraction Layer
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``TypedEnv`` class is very useful for separating your application from the actual environment variables.
It provides a layer where parsing and normalizing can take place in a centralized fashion.

For example, you might start with this simple implementation::

    class CiBuildEnv(TypedEnv):
        job_id = TypedEnv.Str("BUILD_ID")


Later, as the application gets more complicated, you may expand your implementation like so::

    class CiBuildEnv(TypedEnv):
        is_travis = TypedEnv.Bool("TRAVIS", default=False)
        _travis_job_id = TypedEnv.Str("TRAVIS_JOB_ID")
        _jenkins_job_id = TypedEnv.Str("BUILD_ID")

        @property
        def job_id(self):
            return self._travis_job_id if self.is_travis else self._jenkins_job_id



TypedEnv vs. local.env
^^^^^^^^^^^^^^^^^^^^^^

It is important to note that ``TypedEnv`` is separate and unrelated to the ``LocalEnv`` object that is provided via ``local.env``.

While ``TypedEnv`` reads and writes directly to ``os.environ``,
``local.env`` is a frozen copy taken at the start of the python session.

While ``TypedEnv`` is focused on parsing environment variables to be used by the current process,
``local.env``'s primary purpose is to manipulate the environment for child processes that are spawned
via plumbum's :ref:`local commands <guide-local-commands>`.