Skip to content

Commit

Permalink
Merge pull request #219 from apocelipes/feat-limit-worker-numbers
Browse files Browse the repository at this point in the history
feat(server): Read default configs from environment variables
  • Loading branch information
fenngwd authored Apr 20, 2022
2 parents be3cea5 + eb026cc commit 7abef3d
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ python:
- '3.7'
- '3.8'
install:
- pip install -U importlib-metadata
- pip list
- pip install -r test-requirements.txt -U
script:
- echo $(git log -1 --pretty=%B) > latest_commit_msg; pre-commit run --hook-stage commit-msg commitlint --commit-msg-filename latest_commit_msg; rm -rf latest_commit_msg
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
## [Unreleased]
### Added
- Added `post_ready` signal that will be sended after sea app is ready
- Added reading default config from environment variables, will overwrite the config file

## [2.3.2] - 2022-01-12
### Changed
Expand Down
2 changes: 2 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
程序运行的时候,会根据 `SEA_ENV` 环境变量的值加载同名的 `configs` 子模块。需要注意:
**配置名称不得包含小写字母,否则会被忽略。**

**和配置文件中配置项同名的环境变量优先级更高,会覆盖配置文件中的值,例如环境变量`GRPC_WORKERS`将覆盖配置文件中的GRPC_WORKERS。**

## 基本配置

`DEBUG`
Expand Down
2 changes: 2 additions & 0 deletions sea/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ def create_app(root_path=None):
app_class = import_string("app:App")
_app = app_class(root_path, env=env)
_app.config.from_object(config)
# only filter default configurations
_app.config.load_config_from_env()

_app.load_middlewares()
_app.load_extensions_in_module(import_string("app.extensions"))
Expand Down
22 changes: 22 additions & 0 deletions sea/config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import numbers
import os

from sea.datatypes import ConstantsObject
from sea.utils import strtobool


class ConfigAttribute:
Expand Down Expand Up @@ -45,5 +49,23 @@ def get_namespace(self, namespace, lowercase=True, trim_namespace=True):
rv[key] = v
return ConstantsObject(rv)

def load_config_from_env(self):
"""
read environment variables and overwrite same name key's values.
`True` will be converted to python's bool `True`.
`1` will be converted to python's int `1`.
"""
keys = self.keys()

for k in keys:
env_value = os.getenv(k)
if not env_value:
continue
value_type = type(self[k])
if value_type is bool:
self[k] = strtobool(env_value)
elif isinstance(env_value, (str, numbers.Number)):
self[k] = value_type(env_value)

def __repr__(self):
return '<%s %s>' % (self.__class__.__name__, dict.__repr__(self))
16 changes: 16 additions & 0 deletions sea/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,19 @@ def logger_has_level_handler(logger):
current = current.parent

return False


def strtobool(val):
"""Convert a string representation of truth to true (1) or false (0).
True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if
'val' is anything else.
"""
val = val.lower()
if val in ('y', 'yes', 't', 'true', 'on', '1'):
return True
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
return False
else:
raise ValueError("invalid truth value %r" % (val,))
4 changes: 4 additions & 0 deletions tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ def test_baseapp(caplog):
from configs import testing

_app.config.from_object(testing)
assert _app.config["PORT"] == 4000
os.environ["PORT"] = "4001"
_app.config.load_config_from_env()
assert _app.config["PORT"] == 4001
assert _app.debug
assert _app.testing
_app.load_middlewares()
Expand Down
21 changes: 21 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import os

from sea.config import ConfigAttribute, Config

Expand Down Expand Up @@ -29,6 +30,26 @@ class Test(Base):
assert '<Config' in s


def test_config_load_from_env():
config = Config('.', {'KEY_INT': 1, 'KEY_STR': 'str', 'KEY_BOOL': True})
os.environ['KEY_INT'] = "300"
os.environ['KEY_STR'] = "TESTING"
os.environ['KEY_BOOL'] = "False"

assert config['KEY_INT'] == 1
assert config['KEY_STR'] == 'str'
assert config['KEY_BOOL'] == True # noqa

config.load_config_from_env()
assert config['KEY_INT'] == 300
assert config['KEY_STR'] == 'TESTING'
assert config['KEY_BOOL'] == False # noqa

os.environ['TEST'] = 'True'
config.load_config_from_env()
assert 'TEST' not in config


def test_config_attribute():
class App:
x = ConfigAttribute('n_x', json.loads)
Expand Down
1 change: 1 addition & 0 deletions tests/wd/configs/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@

TESTING = True
DEBUG = True
PORT = 4000

0 comments on commit 7abef3d

Please sign in to comment.