forked from bentoml/BentoML
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BentoML configuration base (bentoml#158)
* implementation of python configparser and env var based configuration * added apiserver config as an example * Breaking change: changed home folder from ~/.bentoml to ~/bentoml
- Loading branch information
Showing
18 changed files
with
284 additions
and
61 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 |
---|---|---|
@@ -1,13 +1,32 @@ | ||
# Copyright 2019 Atalaya Tech, Inc. | ||
|
||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
|
||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
include README.md | ||
graft docs | ||
include LICENSE | ||
|
||
# include ".cfg" files | ||
graft bentoml/config | ||
|
||
# Don't include examples, tests directory | ||
prune examples | ||
prune tests | ||
prune docs | ||
|
||
# Patterns to exclude from any directory | ||
global-exclude *~ | ||
global-exclude *.pyc | ||
global-exclude *.pyo | ||
global-exclude .git | ||
global-exclude .ipynb_checkpoints | ||
global-exclude __pycache__ |
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
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
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
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
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,67 @@ | ||
# Copyright 2019 Atalaya Tech, Inc. | ||
|
||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
|
||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from __future__ import absolute_import | ||
from __future__ import division | ||
from __future__ import print_function | ||
|
||
import os | ||
import logging | ||
|
||
from bentoml.utils import Path | ||
from bentoml.exceptions import BentoMLConfigException | ||
from bentoml.config.configparser import BentoConfigParser | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def expand_env_var(env_var): | ||
"""Expands potentially nested env var by repeatedly applying `expandvars` and | ||
`expanduser` until interpolation stops having any effect. | ||
""" | ||
if not env_var: | ||
return env_var | ||
while True: | ||
interpolated = os.path.expanduser(os.path.expandvars(str(env_var))) | ||
if interpolated == env_var: | ||
return interpolated | ||
else: | ||
env_var = interpolated | ||
|
||
|
||
BENTOML_HOME = expand_env_var(os.environ.get("BENTOML_HOME", "~/bentoml")) | ||
try: | ||
Path(BENTOML_HOME).mkdir(exist_ok=True) | ||
except OSError as err: | ||
raise BentoMLConfigException( | ||
"Error creating bentoml home dir '{}': {}".format(BENTOML_HOME, err.strerror) | ||
) | ||
|
||
# Default bentoml config comes with the library bentoml/config/default_bentoml.cfg | ||
DEFAULT_CONFIG_FILE = os.path.join(os.path.dirname(__file__), "default_bentoml.cfg") | ||
with open(DEFAULT_CONFIG_FILE, "rb") as f: | ||
DEFAULT_CONFIG = f.read().decode("utf-8") | ||
|
||
if "BENTML_CONFIG" in os.environ: | ||
# User local config file for customizing bentoml | ||
BENTOML_CONFIG_FILE = expand_env_var(os.environ.get("BENTML_CONFIG")) | ||
else: | ||
BENTOML_CONFIG_FILE = os.path.join(BENTOML_HOME, "bentoml.cfg") | ||
if not os.path.isfile(BENTOML_CONFIG_FILE): | ||
logger.info("Creating new Bentoml config file: %s", BENTOML_CONFIG_FILE) | ||
with open(BENTOML_CONFIG_FILE, "w") as f: | ||
f.write(DEFAULT_CONFIG) | ||
|
||
config = BentoConfigParser(default_config=DEFAULT_CONFIG) | ||
config.read(BENTOML_CONFIG_FILE) |
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,99 @@ | ||
# Copyright 2019 Atalaya Tech, Inc. | ||
|
||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
|
||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from __future__ import absolute_import | ||
from __future__ import division | ||
from __future__ import print_function | ||
|
||
import os | ||
import logging | ||
from collections import OrderedDict | ||
|
||
from configparser import ConfigParser | ||
|
||
from bentoml.exceptions import BentoMLConfigException | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class BentoConfigParser(ConfigParser): | ||
""" BentoML configuration parser | ||
:param default_config string - serve as default value when conf key not presented in | ||
environment var or user local config file | ||
""" | ||
|
||
def __init__(self, default_config, *args, **kwargs): | ||
ConfigParser.__init__(self, *args, **kwargs) | ||
|
||
self.bentoml_defaults = ConfigParser(*args, **kwargs) | ||
if default_config is not None: | ||
self.bentoml_defaults.read_string(default_config) | ||
|
||
@staticmethod | ||
def _env_var_name(section, key): | ||
return "BENTOML__{}__{}".format(section.upper(), key.upper()) | ||
|
||
def get(self, section, key, **kwargs): | ||
""" A simple hierachical config access, priority order: | ||
1. environment var | ||
2. user config file | ||
3. bentoml default config file | ||
""" | ||
section = str(section).lower() | ||
key = str(key).lower() | ||
|
||
env_var = self._env_var_name(section, key) | ||
if env_var in os.environ: | ||
return os.environ[env_var] | ||
|
||
if ConfigParser.has_option(self, section, key): | ||
return ConfigParser.get(self, section, key, **kwargs) | ||
|
||
if self.bentoml_defaults.has_option(section, key): | ||
return self.bentoml_defaults.get(section, key, **kwargs) | ||
else: | ||
raise BentoMLConfigException( | ||
"section/key '{}/{}' not found in BentoML config".format(section, key) | ||
) | ||
|
||
def as_dict(self, display_source=False): | ||
cfg = {} | ||
|
||
def add_config(cfg, source, config): | ||
for section in config: | ||
cfg.setdefault(section, OrderedDict()) | ||
for k, val in config.items(section=section, raw=False): | ||
if display_source: | ||
cfg[section][k] = (val, source) | ||
else: | ||
cfg[section][k] = val | ||
|
||
add_config(cfg, "default", self.bentoml_defaults) | ||
add_config(cfg, "bentoml.cfg", self) | ||
|
||
for ev in os.environ: | ||
if ev.startswith("BENTOML__"): | ||
_, section, key = ev.split("__") | ||
val = os.environ[ev] | ||
if display_source: | ||
val = (val, "env var") | ||
cfg.setdefault(section.lower(), OrderedDict()).update( | ||
{key.lower(): val} | ||
) | ||
|
||
return cfg | ||
|
||
def __repr__(self): | ||
return "<BentoML config: {}>".format(str(self.as_dict())) |
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
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
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
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
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
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
Oops, something went wrong.