Source code for superdjango.env.library

# Imports

from configparser import ConfigParser
from superdjango.utils import smart_cast
import os

# Exports

__all__ = (
    "Env",
    "Section",
)

# Classes


[docs]class Env(object): """The Env class assists with loading environment variables from an INI file. The file may be located anywhere that is accessible for reading by the user that executes the Python process. .. code-block:: ini ; All variables defined in the environment section are available as attributes of the Env instance. For example, ; env.debug [environment] debug = no name = live [database] host = db.example.com name = example_com password = dbpassword user = example_com [mailgun] api_key = mailgunapikey enabled = yes sender_domain = mg.example.com [secret] key = somesupersecretkey In your ``settings.py`` file: .. code-block:: python from superdjango.env import Env env = Env("env.ini") SECRET_KEY = env.secret.key if env.name == "live": DEBUG = False else: DEBUG = True DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'HOST': env.database.host, 'NAME': env.database.name, 'PASSWORD': env.database.password, 'USER': env.database.user, } } # ... and so on ... """
[docs] def __init__(self, path, autoload=True): """Initialize the environment. :param path: The path to the INI file. :type path: str :param autoload: Automatically load the file upon instantiation. See ``load()``. :type autoload: bool """ self.is_loaded = False self.path = path self._sections = dict() if autoload: self.load()
def __getattr__(self, item): """Get a section instance, or if the item exists in the ``environment`` section, get the value of the item.""" if self.has(item): return self._sections.get(item) if self.has("environment", key=item): return self._sections['environment'].values[item] return Section(item)
[docs] def get(self, section, default=None, key=None): """Get a section, and optionally a variable within that section. :param section: The section name. :type section: str :param default: The default value if the key does not exist. :param key: The name of the variable to get from the section. :type key: str """ if not self.has(section, key=key): return default _section = self._sections[section] if key is not None: return _section.values.get(key, default) return _section
[docs] def has(self, section, key=None): """Determine if a section exists. :param section: The section name. :type section: str :param key: Also check whether the given variable exists within the section. :type key: str """ if section not in self._sections: return False if key is not None: return key in self._sections[section].values return True
[docs] def load(self): """Load the environment. :rtype: bool """ if not os.path.exists(self.path): return False ini = ConfigParser() ini.read(self.path) for section in ini.sections(): kwargs = dict() for key, value in ini.items(section): kwargs[key] = smart_cast(value) self._sections[section] = Section(section, **kwargs) self.is_loaded = True return True
[docs]class Section(object): """A section within an Env INI file."""
[docs] def __init__(self, section_name, **kwargs): """Initialize section attributes. :param section_name: The name of the section. Note that no section in your INI may include a variable named ``section_name``. :type section_name: str Keyword arguments are available as attributes of the section instance. """ self._name = section_name self.values = kwargs
def __getattr__(self, item): return self.values.get(item)