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

Auto formatting with python/black #157

Merged
merged 11 commits into from Jun 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .flake8
@@ -0,0 +1,3 @@
[flake8]
ignore = E203, E266, W503
max-line-length = 88
17 changes: 10 additions & 7 deletions .pep8speaks.yml
@@ -1,20 +1,23 @@
scanner:
diff_only: True
linter: pycodestyle

pycodestyle:
max-line-length: 100
linter: flake8

flake8:
max-line-length: 88
ignore:
- E203
- E266
- W503
exclude: [ 'examples' ]

only_mention_files_with_errors: True

message:
opened:
header: "Hello @{name}! Thanks for opening this PR."
footer: "Please update this PR"
footer: "Do see the [Hitchhiker's guide to code style](https://goo.gl/hqbW4r)"
updated:
header: "Hello @{name}, Thanks for updating this PR."
footer:
no_errors: "There are currently no PEP 8 issues detected in this PR. Cheers! :beers:"
footer: ""
no_errors: "There are currently no PEP 8 issues detected in this PR. Cheers! :beers:"

2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -11,7 +11,7 @@ python:

install:
- "pip install --upgrade pip"
- "pip install .[test]"
- "pip install -e .[test]"

script:
- pytest --cov=bentoml
Expand Down
19 changes: 18 additions & 1 deletion DEVELOPMENT.md
Expand Up @@ -64,4 +64,21 @@ If you want to run tests under conda for specific version, use `-e` option:
$ tox -e py2.7
// or
$ tox -e py3.6
```
```

## Style check and auto-formatting your code

Make sure to install all dev dependencies:
```bash
$ pip install -e .[dev]

# For zsh users, use:
$ pip install -e .\[dev\]
```

Run linter/format script:
```bash
./script/format.sh

./script/lint.sh
```
22 changes: 17 additions & 5 deletions bentoml/__init__.py
Expand Up @@ -12,20 +12,32 @@
# 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

from bentoml import handlers
from bentoml.version import __version__

from bentoml.service import BentoService, api_decorator as api, \
env_decorator as env, artifacts_decorator as artifacts, \
ver_decorator as ver
from bentoml.service import (
BentoService,
api_decorator as api,
env_decorator as env,
artifacts_decorator as artifacts,
ver_decorator as ver,
)
from bentoml.server import metrics
from bentoml.archive import save, load

__all__ = [
'__version__', 'api', 'env', 'artifacts', 'BentoService', 'save', 'load', 'handlers', 'metrics'
"__version__",
"api",
"env",
"ver",
"artifacts",
"BentoService",
"save",
"load",
"handlers",
"metrics",
]
2 changes: 1 addition & 1 deletion bentoml/archive/__init__.py
Expand Up @@ -19,4 +19,4 @@
from bentoml.archive.archiver import save
from bentoml.archive.loader import load, load_bentoml_config, load_bento_service_class

__all__ = ['save', 'load', 'load_bentoml_config', 'load_bento_service_class']
__all__ = ["save", "load", "load_bentoml_config", "load_bento_service_class"]
94 changes: 59 additions & 35 deletions bentoml/archive/archiver.py
Expand Up @@ -12,7 +12,6 @@
# 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
Expand All @@ -26,9 +25,13 @@
from bentoml.utils.s3 import is_s3_url, upload_to_s3
from bentoml.utils.tempdir import TempDirectory
from bentoml.archive.py_module_utils import copy_used_py_modules
from bentoml.archive.templates import BENTO_MODEL_SETUP_PY_TEMPLATE, \
MANIFEST_IN_TEMPLATE, BENTO_SERVICE_DOCKERFILE_CPU_TEMPLATE, \
BENTO_SERVICE_DOCKERFILE_SAGEMAKER_TEMPLATE, INIT_PY_TEMPLATE
from bentoml.archive.templates import (
BENTO_MODEL_SETUP_PY_TEMPLATE,
MANIFEST_IN_TEMPLATE,
BENTO_SERVICE_DOCKERFILE_CPU_TEMPLATE,
BENTO_SERVICE_DOCKERFILE_SAGEMAKER_TEMPLATE,
INIT_PY_TEMPLATE,
)
from bentoml.archive.config import BentoArchiveConfig

DEFAULT_BENTO_ARCHIVE_DESCRIPTION = """\
Expand All @@ -44,20 +47,22 @@ def _validate_version_str(version_str):
"""
regex = r"[A-Za-z0-9_.-]{1,128}\Z"
if re.match(regex, version_str) is None:
raise ValueError('Invalid BentoArchive version: "{}", it can only consist'
' ALPHA / DIGIT / "-" / "." / "_", and must be less than'
'128 characthers'.format(version_str))
raise ValueError(
'Invalid BentoArchive version: "{}", it can only consist'
' ALPHA / DIGIT / "-" / "." / "_", and must be less than'
"128 characthers".format(version_str)
)


def _generate_new_version_str():
"""
Generate a version string in the format of YYYY-MM-DD-Hash
"""
time_obj = datetime.now()
date_string = time_obj.strftime('%Y_%m_%d')
date_string = time_obj.strftime("%Y_%m_%d")
random_hash = uuid.uuid4().hex[:8]

return date_string + '_' + random_hash
return date_string + "_" + random_hash


def save(bento_service, dst, version=None):
Expand All @@ -69,15 +74,22 @@ def save(bento_service, dst, version=None):
version = _generate_new_version_str()
_validate_version_str(version)

if bento_service._version_major is not None and bento_service._version_minor is not None:
if (
bento_service._version_major is not None
and bento_service._version_minor is not None
):
# BentoML uses semantic versioning for BentoService distribution
# when user specified the MAJOR and MINOR version number along with
# the BentoService class definition with '@ver' decorator.
# The parameter version(or auto generated version) here will be used as
# PATCH field in the final version:
version = '.'.join(
[str(bento_service._version_major),
str(bento_service._version_minor), version])
version = ".".join(
[
str(bento_service._version_major),
str(bento_service._version_minor),
version,
]
)

# Full path containing saved BentoArchive, it the dst path with service name
# and service version as prefix. e.g.:
Expand All @@ -101,8 +113,10 @@ def _save(bento_service, dst, version=None):
path = os.path.join(dst, bento_service.name, version)

if os.path.exists(path):
raise ValueError("Version {version} in Path: {dst} already "
"exist.".format(version=version, dst=dst))
raise ValueError(
"Version {version} in Path: {dst} already "
"exist.".format(version=version, dst=dst)
)

os.mkdir(path)
module_base_path = os.path.join(path, bento_service.name)
Expand All @@ -113,7 +127,7 @@ def _save(bento_service, dst, version=None):
model_description = bento_service.__class__.__doc__.strip()
else:
model_description = DEFAULT_BENTO_ARCHIVE_DESCRIPTION
with open(os.path.join(path, 'README.md'), 'w') as f:
with open(os.path.join(path, "README.md"), "w") as f:
f.write(model_description)

# save all model artifacts to 'base_path/name/artifacts/' directory
Expand All @@ -122,42 +136,52 @@ def _save(bento_service, dst, version=None):
# write conda environment, requirement.txt
bento_service.env.save(path)

# TODO: add bentoml.find_packages helper for more fine grained control over
# this process, e.g. packages=find_packages(base, [], exclude=[], used_module_only=True)
# TODO: add bentoml.find_packages helper for more fine grained control over this
# process, e.g. packages=find_packages(base, [], exclude=[], used_module_only=True)
# copy over all custom model code
module_name, module_file = copy_used_py_modules(bento_service.__class__.__module__,
os.path.join(path, bento_service.name))
module_name, module_file = copy_used_py_modules(
bento_service.__class__.__module__, os.path.join(path, bento_service.name)
)

# create __init__.py
with open(os.path.join(path, bento_service.name, '__init__.py'), "w") as f:
with open(os.path.join(path, bento_service.name, "__init__.py"), "w") as f:
f.write(
INIT_PY_TEMPLATE.format(service_name=bento_service.name, module_name=module_name,
pypi_package_version=version))
INIT_PY_TEMPLATE.format(
service_name=bento_service.name,
module_name=module_name,
pypi_package_version=version,
)
)

# write setup.py, make exported model pip installable
setup_py_content = BENTO_MODEL_SETUP_PY_TEMPLATE.format(
name=bento_service.name, pypi_package_version=version, long_description=model_description)
with open(os.path.join(path, 'setup.py'), 'w') as f:
name=bento_service.name,
pypi_package_version=version,
long_description=model_description,
)
with open(os.path.join(path, "setup.py"), "w") as f:
f.write(setup_py_content)

with open(os.path.join(path, 'MANIFEST.in'), 'w') as f:
with open(os.path.join(path, "MANIFEST.in"), "w") as f:
f.write(MANIFEST_IN_TEMPLATE.format(service_name=bento_service.name))

# write Dockerfile
with open(os.path.join(path, 'Dockerfile'), 'w') as f:
with open(os.path.join(path, "Dockerfile"), "w") as f:
f.write(BENTO_SERVICE_DOCKERFILE_CPU_TEMPLATE)
with open(os.path.join(path, 'Dockerfile-sagemaker'), 'w') as f:
with open(os.path.join(path, "Dockerfile-sagemaker"), "w") as f:
f.write(BENTO_SERVICE_DOCKERFILE_SAGEMAKER_TEMPLATE)

# write bentoml.yml
config = BentoArchiveConfig()
config["metadata"].update({
'service_name': bento_service.name,
'service_version': version,
'module_name': module_name,
'module_file': module_file,
})
config['env'] = bento_service.env.to_dict()
config["metadata"].update(
{
"service_name": bento_service.name,
"service_version": version,
"module_name": module_name,
"module_file": module_file,
}
)
config["env"] = bento_service.env.to_dict()

config.write_to_path(path)
# Also write bentoml.yml to module base path to make it accessible
Expand Down
26 changes: 15 additions & 11 deletions bentoml/archive/config.py
Expand Up @@ -12,7 +12,6 @@
# 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
Expand All @@ -34,28 +33,33 @@


class BentoArchiveConfig(object):

def __init__(self, kind='BentoService'):
def __init__(self, kind="BentoService"):
self.kind = kind
self._yaml = YAML()
self._yaml.default_flow_style = False
self.config = self._yaml.load(
BENTOML_CONFIG_YAML_TEPMLATE.format(kind=self.kind, bentoml_version=BENTOML_VERSION,
created_at=str(datetime.now())))

def write_to_path(self, path, filename='bentoml.yml'):
BENTOML_CONFIG_YAML_TEPMLATE.format(
kind=self.kind,
bentoml_version=BENTOML_VERSION,
created_at=str(datetime.now()),
)
)

def write_to_path(self, path, filename="bentoml.yml"):
return self._yaml.dump(self.config, Path(os.path.join(path, filename)))

@classmethod
def load(cls, filepath):
conf = cls()
with open(filepath, 'rb') as config_file:
with open(filepath, "rb") as config_file:
yml_content = config_file.read()
conf.config = conf._yaml.load(yml_content)

if conf['version'] != BENTOML_VERSION:
raise ValueError("BentoArchive version mismatch: loading archive bundled in version {},"
"but loading from version {}".format(conf['version'], BENTOML_VERSION))
if conf["version"] != BENTOML_VERSION:
raise ValueError(
"BentoArchive version mismatch: loading archive bundled in version {},"
"but loading from version {}".format(conf["version"], BENTOML_VERSION)
)

return conf

Expand Down