Merge pull request #1436 from jotagesales/config_from_object_string
Config from object string
This commit is contained in:
commit
8fbbe94fe1
|
@ -53,6 +53,13 @@ import myapp.default_settings
|
|||
app = Sanic('myapp')
|
||||
app.config.from_object(myapp.default_settings)
|
||||
```
|
||||
or also by path to config:
|
||||
|
||||
```
|
||||
app = Sanic('myapp')
|
||||
app.config.from_object('config.path.config.Class')
|
||||
```
|
||||
|
||||
|
||||
You could use a class or any other object as well.
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import os
|
|||
import types
|
||||
|
||||
from sanic.exceptions import PyFileError
|
||||
from sanic.helpers import import_string
|
||||
|
||||
|
||||
SANIC_PREFIX = "SANIC_"
|
||||
|
@ -102,6 +103,9 @@ class Config(dict):
|
|||
from yourapplication import default_config
|
||||
app.config.from_object(default_config)
|
||||
|
||||
or also:
|
||||
app.config.from_object('myproject.config.MyConfigClass')
|
||||
|
||||
You should not use this function to load the actual configuration but
|
||||
rather configuration defaults. The actual config should be loaded
|
||||
with :meth:`from_pyfile` and ideally from a location not within the
|
||||
|
@ -109,6 +113,8 @@ class Config(dict):
|
|||
|
||||
:param obj: an object holding the configuration
|
||||
"""
|
||||
if isinstance(obj, str):
|
||||
obj = import_string(obj)
|
||||
for key in dir(obj):
|
||||
if key.isupper():
|
||||
self[key] = getattr(obj, key)
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
"""Defines basics of HTTP standard."""
|
||||
|
||||
from importlib import import_module
|
||||
from inspect import ismodule
|
||||
|
||||
|
||||
STATUS_CODES = {
|
||||
100: b"Continue",
|
||||
101: b"Switching Protocols",
|
||||
|
@ -131,3 +135,21 @@ def remove_entity_headers(headers, allowed=("content-location", "expires")):
|
|||
if not is_entity_header(header) or header.lower() in allowed
|
||||
}
|
||||
return headers
|
||||
|
||||
|
||||
def import_string(module_name, package=None):
|
||||
"""
|
||||
import a module or class by string path.
|
||||
|
||||
:module_name: str with path of module or path to import and
|
||||
instanciate a class
|
||||
:returns: a module object or one instance from class if
|
||||
module_name is a valid path to class
|
||||
|
||||
"""
|
||||
module, klass = module_name.rsplit(".", 1)
|
||||
module = import_module(module, package=package)
|
||||
obj = getattr(module, klass)
|
||||
if ismodule(obj):
|
||||
return obj
|
||||
return obj()
|
||||
|
|
|
@ -18,17 +18,30 @@ def temp_path():
|
|||
yield Path(td, "file")
|
||||
|
||||
|
||||
def test_load_from_object(app):
|
||||
class Config:
|
||||
not_for_config = "should not be used"
|
||||
CONFIG_VALUE = "should be used"
|
||||
class ConfigTest:
|
||||
not_for_config = 'should not be used'
|
||||
CONFIG_VALUE = 'should be used'
|
||||
|
||||
app.config.from_object(Config)
|
||||
|
||||
def test_load_from_object(app):
|
||||
app.config.from_object(ConfigTest)
|
||||
assert "CONFIG_VALUE" in app.config
|
||||
assert app.config.CONFIG_VALUE == "should be used"
|
||||
assert "not_for_config" not in app.config
|
||||
|
||||
|
||||
def test_load_from_object_string(app):
|
||||
app.config.from_object('test_config.ConfigTest')
|
||||
assert 'CONFIG_VALUE' in app.config
|
||||
assert app.config.CONFIG_VALUE == 'should be used'
|
||||
assert 'not_for_config' not in app.config
|
||||
|
||||
|
||||
def test_load_from_object_string_exception(app):
|
||||
with pytest.raises(ImportError):
|
||||
app.config.from_object('test_config.Config.test')
|
||||
|
||||
|
||||
def test_auto_load_env():
|
||||
environ["SANIC_TEST_ANSWER"] = "42"
|
||||
app = Sanic()
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import inspect
|
||||
|
||||
from sanic import helpers
|
||||
from sanic.config import Config
|
||||
import pytest
|
||||
|
||||
|
||||
def test_has_message_body():
|
||||
|
@ -56,3 +60,18 @@ def test_remove_entity_headers():
|
|||
|
||||
for header, expected in tests:
|
||||
assert helpers.remove_entity_headers(header) == expected
|
||||
|
||||
|
||||
def test_import_string_class():
|
||||
obj = helpers.import_string('sanic.config.Config')
|
||||
assert isinstance(obj, Config)
|
||||
|
||||
|
||||
def test_import_string_module():
|
||||
module = helpers.import_string('sanic.config')
|
||||
assert inspect.ismodule(module)
|
||||
|
||||
|
||||
def test_import_string_exception():
|
||||
with pytest.raises(ImportError):
|
||||
helpers.import_string('test.test.test')
|
||||
|
|
Loading…
Reference in New Issue
Block a user