This repository has been archived by the owner on Jan 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
333 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[bumpversion] | ||
files = setup.py envcfg/__init__.py | ||
commit = True | ||
tag = False | ||
current_version = 0.1.0 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
language: python | ||
python: | ||
- "2.7" | ||
- "3.3" | ||
- "3.4" | ||
- "pypy" | ||
install: | ||
- "pip install ." | ||
- "pip install pytest>=2.4.2 -U" | ||
- "pip install pytest-cov pytest-pep8 coveralls" | ||
- "touch tests/__init__.py" | ||
script: "py.test --cov envcfg --pep8 tests" | ||
after_success: | ||
coveralls | ||
branches: | ||
only: | ||
- master | ||
- develop |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
The MIT License (MIT) | ||
Copyright (c) 2014 Jiangge Zhang | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE | ||
OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
|Build Status| |Coverage Status| |PyPI Version| |PyPI Downloads| |Wheel Status| | ||
|
||
python-envcfg | ||
============= | ||
|
||
Accessing environment variables with a magic module. | ||
|
||
:: | ||
|
||
>>> import os | ||
>>> from envcfg.raw.python import CONFIGURE_OPTS | ||
>>> | ||
>>> CONFIGURE_OPTS | ||
'--enable-shared --enable-universalsdk=/ --with-universal-archs=intel' | ||
>>> CONFIGURE_OPTS == os.environ['PYTHON_CONFIGURE_OPTS'] | ||
True | ||
|
||
It works with many frameworks such as Django and Flask. Then you can store your | ||
config in the environment variables instead of framework-specific config files. | ||
It is recommended by 12-Factor_. | ||
|
||
|
||
Installation | ||
------------ | ||
|
||
:: | ||
|
||
$ pip install envcfg | ||
$ pip freeze > requirements.txt # http://nvie.com/posts/pin-your-packages/ | ||
|
||
|
||
Issues | ||
------ | ||
|
||
If you want to report bugs or request features, please create issues on | ||
`GitHub Issues <https://github.com/tonyseek/python-envcfg/issues>`_. | ||
|
||
|
||
.. _12-Factor: http://12factor.net | ||
|
||
.. |Build Status| image:: https://travis-ci.org/tonyseek/python-envcfg.svg?branch=master,develop | ||
:target: https://travis-ci.org/tonyseek/python-envcfg | ||
:alt: Build Status | ||
.. |Coverage Status| image:: https://img.shields.io/coveralls/tonyseek/python-envcfg/develop.svg | ||
:target: https://coveralls.io/r/tonyseek/python-envcfg | ||
:alt: Coverage Status | ||
.. |Wheel Status| image:: https://pypip.in/wheel/python-envcfg/badge.svg | ||
:target: https://warehouse.python.org/project/python-envcfg | ||
:alt: Wheel Status | ||
.. |PyPI Version| image:: https://img.shields.io/pypi/v/python-envcfg.svg | ||
:target: https://pypi.python.org/pypi/python-envcfg | ||
:alt: PyPI Version | ||
.. |PyPI Downloads| image:: https://img.shields.io/pypi/dm/python-envcfg.svg | ||
:target: https://pypi.python.org/pypi/python-envcfg | ||
:alt: Downloads |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__version__ = '0.1.0' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import os | ||
import re | ||
import sys | ||
import types | ||
|
||
|
||
class ImportHook(object): | ||
|
||
re_module_name = re.compile(r'[a-z][a-z0-9_]*') | ||
|
||
def __init__(self, wrapper_module, value_processor): | ||
self.wrapper_module = wrapper_module | ||
self.wrapper_prefix = wrapper_module + '.' | ||
self.value_processor = value_processor | ||
|
||
def __eq__(self, other): | ||
return self.__class__.__module__ == other.__class__.__module__ and \ | ||
self.__class__.__name__ == other.__class__.__name__ and \ | ||
self.wrapper_module == other.wrapper_module | ||
|
||
def __ne__(self, other): | ||
return not self.__eq__(other) | ||
|
||
def install(self): | ||
sys.meta_path[:] = [x for x in sys.meta_path if self != x] + [self] | ||
|
||
def find_module(self, fullname, path=None): | ||
if fullname.startswith(self.wrapper_prefix): | ||
return self | ||
|
||
def load_module(self, fullname): | ||
if fullname in sys.modules: | ||
return sys.modules[fullname] | ||
|
||
prefix_name = fullname[len(self.wrapper_prefix):] | ||
if not self.re_module_name.match(prefix_name): | ||
error_msg = ('No module named {0}\n\nThe name of envvar module ' | ||
'should matched {1.pattern}') | ||
raise ImportError(error_msg.format(fullname, self.re_module_name)) | ||
|
||
module = types.ModuleType(fullname) | ||
for name, value in self.load_environ(prefix_name): | ||
setattr(module, name, value) | ||
sys.modules[fullname] = module | ||
|
||
return module | ||
|
||
def load_environ(self, prefix_name): | ||
prefix = prefix_name.upper() + '_' | ||
for raw_name, raw_value in os.environ.items(): | ||
if not raw_name.startswith(prefix): | ||
continue | ||
if raw_name == prefix: | ||
continue | ||
name = raw_name[len(prefix):] | ||
value = self.value_processor(name, raw_name, raw_value) | ||
yield name, value | ||
|
||
|
||
def import_hook(wrapper_module): | ||
def wrapper(fn): | ||
hook = ImportHook(wrapper_module, value_processor=fn) | ||
hook.install() | ||
return wrapper |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from __future__ import absolute_import | ||
|
||
from .._hook import import_hook | ||
|
||
|
||
@import_hook(__name__) | ||
def value_processor(name, raw_name, raw_value): | ||
import json | ||
try: | ||
value = json.loads(raw_value) | ||
except ValueError: | ||
error_msg = ( | ||
'{0}={1!r} found but {1!r} is not a valid json value.\n\n' | ||
'You may want {0}=\'"{1}"\' if the value should be a string.') | ||
raise ImportError(error_msg.format(raw_name, raw_value)) | ||
return value | ||
|
||
|
||
del import_hook | ||
del value_processor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from __future__ import absolute_import | ||
|
||
from .._hook import import_hook | ||
|
||
|
||
@import_hook(__name__) | ||
def value_processor(name, raw_name, raw_value): | ||
return raw_value | ||
|
||
|
||
del import_hook | ||
del value_processor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[pytest] | ||
pep8ignore = | ||
docs/conf.py ALL | ||
docs/_themes/* ALL | ||
[bdist_wheel] | ||
universal = 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
from setuptools import setup, find_packages | ||
|
||
|
||
with open('README.rst') as readme: | ||
next(readme) # skip the first line | ||
long_description = ''.join(readme).strip() | ||
|
||
|
||
setup( | ||
name='python-envcfg', | ||
version='0.1.0', | ||
author='Jiangge Zhang', | ||
author_email='tonyseek@gmail.com', | ||
description='Accessing environment variables with a magic module.', | ||
long_description=long_description, | ||
platforms=['Any'], | ||
url='https://github.com/tonyseek/python-envcfg', | ||
license='MIT', | ||
packages=find_packages(), | ||
classifiers=[ | ||
'Development Status :: 3 - Alpha', | ||
'License :: OSI Approved :: MIT License', | ||
'Operating System :: OS Independent', | ||
'Programming Language :: Python', | ||
'Programming Language :: Python :: 2.7', | ||
'Programming Language :: Python :: 3.3', | ||
'Programming Language :: Python :: 3.4', | ||
'Topic :: Software Development :: Libraries', | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import os | ||
|
||
from pytest import fixture | ||
|
||
|
||
@fixture(scope='function') | ||
def environ(request): | ||
origin = dict(os.environ) | ||
|
||
@request.addfinalizer | ||
def restore_environ(): | ||
os.environ.clear() | ||
os.environ.update(origin) | ||
|
||
return os.environ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
from pytest import raises | ||
|
||
|
||
def test_success(environ): | ||
environ['ENVCFG_JSON_1_BOOLEAN'] = 'true' | ||
environ['ENVCFG_JSON_1_INTEGER'] = '42' | ||
environ['ENVCFG_JSON_1_REAL'] = '42.42' | ||
environ['ENVCFG_JSON_1_STRING'] = '"42"' | ||
environ['ENVCFG_JSON_1_DICT'] = '{"value": 42}' | ||
|
||
from envcfg.json.envcfg_json_1 import ( | ||
BOOLEAN, | ||
INTEGER, | ||
REAL, | ||
STRING, | ||
DICT, | ||
) | ||
assert BOOLEAN is True | ||
assert INTEGER == 42 | ||
assert REAL == 42.42 | ||
assert STRING == '42' | ||
assert DICT == {'value': 42} | ||
|
||
|
||
def test_failed(environ): | ||
environ['ENVCFG_JSON_2_INVALID'] = 'foo' | ||
|
||
with raises(ImportError) as einfo: | ||
import envcfg.json._private_module # noqa | ||
assert einfo.value.args[0].startswith( | ||
'No module named envcfg.json._private_module') | ||
|
||
with raises(ImportError) as einfo: | ||
import envcfg.json.INVALID_NAME # noqa | ||
assert einfo.value.args[0].startswith( | ||
'No module named envcfg.json.INVALID_NAME') | ||
|
||
with raises(ImportError) as einfo: | ||
import envcfg.json.envcfg_json_2 # noqa | ||
assert 'is not a valid json value' in einfo.value.args[0] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
from pytest import raises | ||
|
||
|
||
def test_success(environ): | ||
environ['ENVCFG_RAW_1_BOOLEAN'] = 'true' | ||
environ['ENVCFG_RAW_1_INTEGER'] = '42' | ||
environ['ENVCFG_RAW_1_REAL'] = '42.42' | ||
environ['ENVCFG_RAW_1_STRING'] = '"42"' | ||
environ['ENVCFG_RAW_1_DICT'] = '{"value": 42}' | ||
|
||
from envcfg.raw.envcfg_raw_1 import ( | ||
BOOLEAN, | ||
INTEGER, | ||
REAL, | ||
STRING, | ||
DICT, | ||
) | ||
assert BOOLEAN == 'true' | ||
assert INTEGER == '42' | ||
assert REAL == '42.42' | ||
assert STRING == '"42"' | ||
assert DICT == '{"value": 42}' | ||
|
||
|
||
def test_failed(): | ||
with raises(ImportError) as einfo: | ||
import envcfg.raw._private_module # noqa | ||
assert einfo.value.args[0].startswith( | ||
'No module named envcfg.raw._private_module') | ||
|
||
with raises(ImportError) as einfo: | ||
import envcfg.raw.INVALID_NAME # noqa | ||
assert einfo.value.args[0].startswith( | ||
'No module named envcfg.raw.INVALID_NAME') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[tox] | ||
envlist = py27,py33,py34,pypy | ||
[testenv] | ||
deps = | ||
pytest | ||
pytest-cov | ||
pytest-pep8 | ||
commands = | ||
py.test \ | ||
--cov {envsitepackagesdir}/envcfg \ | ||
--pep8 \ | ||
tests |