environment.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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 ..const import IS_WINDOWS_PLATFORM
  8. from .errors import ConfigurationError
  9. log = logging.getLogger(__name__)
  10. def split_env(env):
  11. if isinstance(env, six.binary_type):
  12. env = env.decode('utf-8', 'replace')
  13. if '=' in env:
  14. return env.split('=', 1)
  15. else:
  16. return env, None
  17. def env_vars_from_file(filename):
  18. """
  19. Read in a line delimited file of environment variables.
  20. """
  21. if not os.path.exists(filename):
  22. raise ConfigurationError("Couldn't find env file: %s" % filename)
  23. elif not os.path.isfile(filename):
  24. raise ConfigurationError("%s is not a file." % (filename))
  25. env = {}
  26. for line in codecs.open(filename, 'r', 'utf-8'):
  27. line = line.strip()
  28. if line and not line.startswith('#'):
  29. k, v = split_env(line)
  30. env[k] = v
  31. return env
  32. class Environment(dict):
  33. def __init__(self, *args, **kwargs):
  34. super(Environment, self).__init__(*args, **kwargs)
  35. self.missing_keys = []
  36. @classmethod
  37. def from_env_file(cls, base_dir):
  38. def _initialize():
  39. result = cls()
  40. if base_dir is None:
  41. return result
  42. env_file_path = os.path.join(base_dir, '.env')
  43. try:
  44. return cls(env_vars_from_file(env_file_path))
  45. except ConfigurationError:
  46. pass
  47. return result
  48. instance = _initialize()
  49. instance.update(os.environ)
  50. return instance
  51. def __getitem__(self, key):
  52. try:
  53. return super(Environment, self).__getitem__(key)
  54. except KeyError:
  55. if IS_WINDOWS_PLATFORM:
  56. try:
  57. return super(Environment, self).__getitem__(key.upper())
  58. except KeyError:
  59. pass
  60. if key not in self.missing_keys:
  61. log.warn(
  62. "The {} variable is not set. Defaulting to a blank string."
  63. .format(key)
  64. )
  65. self.missing_keys.append(key)
  66. return ""
  67. def __contains__(self, key):
  68. result = super(Environment, self).__contains__(key)
  69. if IS_WINDOWS_PLATFORM:
  70. return (
  71. result or super(Environment, self).__contains__(key.upper())
  72. )
  73. return result
  74. def get(self, key, *args, **kwargs):
  75. if IS_WINDOWS_PLATFORM:
  76. return super(Environment, self).get(
  77. key,
  78. super(Environment, self).get(key.upper(), *args, **kwargs)
  79. )
  80. return super(Environment, self).get(key, *args, **kwargs)