Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config from object string #1436

Merged
merged 13 commits into from
Jun 16, 2019
Merged
7 changes: 7 additions & 0 deletions docs/sanic/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ import myapp.default_settings
app = Sanic('myapp')
app.config.from_object(myapp.default_settings)
```
or also by path to config:

```
sjsadowski marked this conversation as resolved.
Show resolved Hide resolved
app = Sanic('myapp')
app.config.from_object('config.path.config.Class')
jotagesales marked this conversation as resolved.
Show resolved Hide resolved
```


You could use a class or any other object as well.

Expand Down
4 changes: 4 additions & 0 deletions sanic/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os
import types

import import_string

from sanic.exceptions import PyFileError


Expand Down Expand Up @@ -111,6 +113,8 @@ def from_object(self, obj):

: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)
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import codecs
import os
import re
from distutils.errors import DistutilsPlatformError

from distutils.util import strtobool

from setuptools import setup
Expand Down Expand Up @@ -63,6 +63,7 @@ def open_local(paths, mode='r', encoding='utf8'):
'aiofiles>=0.3.0',
'websockets>=6.0,<7.0',
'multidict>=4.0,<5.0',
'import-string>=0.1.0'
ahopkins marked this conversation as resolved.
Show resolved Hide resolved
]
if strtobool(os.environ.get("SANIC_NO_UJSON", "no")):
print("Installing without uJSON")
Expand Down
12 changes: 10 additions & 2 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,25 @@ def temp_path():
yield Path(td, 'file')


def test_load_from_object(app):
class Config:
class Config:
Copy link
Contributor

@harshanarayana harshanarayana Mar 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please rename this class from Config to something else? This line is overriding the import done by from sanic.config import Config

This is causing tests to fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@harshanarayana i renamed the class, thank.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renaming this class seems to be the only thing holding it up.

not_for_config = 'should not be used'
CONFIG_VALUE = 'should be used'


def test_load_from_object(app):
app.config.from_object(Config)
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.Config')
assert 'CONFIG_VALUE' in app.config
assert app.config.CONFIG_VALUE == 'should be used'
assert 'not_for_config' not in app.config


def test_auto_load_env():
environ["SANIC_TEST_ANSWER"] = "42"
app = Sanic()
Expand Down