Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Imports
3from configparser import ConfigParser
4from superdjango.utils import smart_cast
5import os
7# Exports
9__all__ = (
10 "Env",
11)
13# Classes
16class Env(object):
17 """The Env class assists with loading environment variables from an INI file.
19 The file may be located anywhere that is accessible for reading by the user that executes the Python process.
21 .. code-block:: ini
23 ; All variables defined in the environment section are available as attributes of the Env instance. For example,
24 ; env.debug
25 [environment]
26 debug = no
27 name = live
29 [database]
30 host = db.example.com
31 name = example_com
32 password = dbpassword
33 user = example_com
35 [mailgun]
36 api_key = mailgunapikey
37 enabled = yes
38 sender_domain = mg.example.com
40 [secret]
41 key = somesupersecretkey
43 In your ``settings.py`` file:
45 .. code-block:: python
47 from superdjango.env import Env
49 env = Env("env.ini")
51 SECRET_KEY = env.secret.key
53 if env.name == "live":
54 DEBUG = False
55 else:
56 DEBUG = True
58 DATABASES = {
59 'default': {
60 'ENGINE': 'django.db.backends.postgresql',
61 'HOST': env.database.host,
62 'NAME': env.database.name,
63 'PASSWORD': env.database.password,
64 'USER': env.database.user,
65 }
66 }
68 # ... and so on ...
70 """
72 def __init__(self, path, autoload=True):
73 """Initialize the environment.
75 :param path: The path to the INI file.
76 :type path: str
78 :param autoload: Automatically load the file upon instantiation. See ``load()``.
79 :type autoload: bool
81 """
82 self.is_loaded = False
83 self.path = path
84 self._sections = dict()
86 if autoload:
87 self.load()
89 def __getattr__(self, item):
90 """Get a section instance, or if the item exists in the ``environment`` section, get the value of the item."""
91 if self.has(item):
92 return self._sections.get(item)
94 if self.has("environment", key=item):
95 return self._sections['environment'].values[item]
97 return Section(item)
99 def get(self, section, default=None, key=None):
100 """Get a section, and optionally a variable within that section.
102 :param section: The section name.
103 :type section: str
105 :param default: The default value if the key does not exist.
107 :param key: The name of the variable to get from the section.
108 :type key: str
110 """
111 if not self.has(section, key=key):
112 return default
114 _section = self._sections[section]
115 if key is not None:
116 return _section.values.get(key, default)
118 return _section
120 def has(self, section, key=None):
121 """Determine if a section exists.
123 :param section: The section name.
124 :type section: str
126 :param key: Also check whether the given variable exists within the section.
127 :type key: str
129 """
130 if section not in self._sections:
131 return False
133 if key is not None:
134 return key in self._sections[section].values
136 return True
138 def load(self):
139 """Load the environment.
141 :rtype: bool
143 """
144 if not os.path.exists(self.path):
145 return False
147 ini = ConfigParser()
148 ini.read(self.path)
150 for section in ini.sections():
151 kwargs = dict()
152 for key, value in ini.items(section):
153 kwargs[key] = smart_cast(value)
155 self._sections[section] = Section(section, **kwargs)
157 self.is_loaded = True
159 return True
162class Section(object):
163 """A section within an Env INI file."""
165 def __init__(self, section_name, **kwargs):
166 """Initialize section attributes.
168 :param section_name: The name of the section. Note that no section in your INI may include a variable named
169 ``section_name``.
170 :type section_name: str
172 Keyword arguments are available as attributes of the section instance.
174 """
175 self._name = section_name
176 self.values = kwargs
178 def __getattr__(self, item):
179 return self.values.get(item)