environment.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. from __future__ import absolute_import
  2. from __future__ import unicode_literals
  3. import codecs
  4. import logging
  5. import os
  6. import six
  7. from .errors import ConfigurationError
  8. log = logging.getLogger(__name__)
  9. def split_env(env):
  10. if isinstance(env, six.binary_type):
  11. env = env.decode('utf-8', 'replace')
  12. if '=' in env:
  13. return env.split('=', 1)
  14. else:
  15. return env, None
  16. def env_vars_from_file(filename):
  17. """
  18. Read in a line delimited file of environment variables.
  19. """
  20. if not os.path.exists(filename):
  21. raise ConfigurationError("Couldn't find env file: %s" % filename)
  22. env = {}
  23. for line in codecs.open(filename, 'r', 'utf-8'):
  24. line = line.strip()
  25. if line and not line.startswith('#'):
  26. k, v = split_env(line)
  27. env[k] = v
  28. return env
  29. class Environment(dict):
  30. def __init__(self, *args, **kwargs):
  31. super(Environment, self).__init__(*args, **kwargs)
  32. self.missing_keys = []
  33. self.update(os.environ)
  34. @classmethod
  35. def from_env_file(cls, base_dir):
  36. result = cls()
  37. if base_dir is None:
  38. return result
  39. env_file_path = os.path.join(base_dir, '.env')
  40. try:
  41. return cls(env_vars_from_file(env_file_path))
  42. except ConfigurationError:
  43. pass
  44. return result
  45. def __getitem__(self, key):
  46. try:
  47. return super(Environment, self).__getitem__(key)
  48. except KeyError:
  49. if key not in self.missing_keys:
  50. log.warn(
  51. "The {} variable is not set. Defaulting to a blank string."
  52. .format(key)
  53. )
  54. self.missing_keys.append(key)
  55. return ""