def from_archive(cls, path): from bentoml.archive import load_bentoml_config # TODO: add model.env.verify() to check dependencies and python version etc if cls._bento_archive_path is not None and cls._bento_archive_path != path: raise BentoMLException( "Loaded BentoArchive(from {}) can't be loaded again from a different" "archive path {}".format(cls._bento_archive_path, path)) if is_s3_url(path): temporary_path = tempfile.mkdtemp() download_from_s3(path, temporary_path) # Use loacl temp path for the following loading operations path = temporary_path artifacts_path = path # For pip installed BentoService, artifacts directory is located at # 'package_path/artifacts/', but for loading from BentoArchive, it is # in 'path/{service_name}/artifacts/' if not os.path.isdir(os.path.join(path, 'artifacts')): artifacts_path = os.path.join(path, cls.name()) bentoml_config = load_bentoml_config(path) # TODO: check archive type and allow loading archive only if bentoml_config['service_name'] != cls.name(): raise BentoMLException( 'BentoService name does not match with BentoML Archive in path: {}' .format(path)) artifacts = ArtifactCollection.load(artifacts_path, cls._artifacts_spec) svc = cls(artifacts) return svc
def serve(port, archive_path=archive_path, with_conda=False): if with_conda: config = load_bentoml_config(archive_path) metadata = config['metadata'] env_name = metadata['service_name'] + '_' + metadata[ 'service_version'] pip_req = os.path.join(archive_path, 'requirements.txt') subprocess.call( 'command -v conda >/dev/null 2>&1 || {{ echo >&2 "--with-conda ' 'parameter requires conda but it\'s not installed."; exit 1; }} && ' 'conda env update -n {env_name} -f {env_file} && ' 'conda init bash && ' 'eval "$(conda shell.bash hook)" && ' 'conda activate {env_name} && ' '{{ [ -f {pip_req} ] && pip install -r {pip_req} || echo "no pip ' 'dependencies."; }} &&' 'bentoml serve {archive_path} --port {port}'.format( env_name=env_name, env_file=os.path.join(archive_path, 'environment.yml'), archive_path=archive_path, port=port, pip_req=pip_req, ), shell=True, ) return track_cli('serve') bento_service = load(archive_path) server = BentoAPIServer(bento_service, port=port) server.start()
def load_from_dir(cls, path): from bentoml.archive import load_bentoml_config if cls._bento_archive_path is not None and cls._bento_archive_path != path: logger.warning( "Loaded BentoArchive from '%s' can't be loaded again from a different" "path %s", cls._bento_archive_path, path, ) artifacts_path = path # For pip installed BentoService, artifacts directory is located at # 'package_path/artifacts/', but for loading from BentoArchive, it is # in 'path/{service_name}/artifacts/' if not os.path.isdir(os.path.join(path, "artifacts")): artifacts_path = os.path.join(path, cls.name()) bentoml_config = load_bentoml_config(path) if bentoml_config["metadata"]["service_name"] != cls.name(): raise BentoMLException( "BentoService name does not match with BentoArchive in path: {}" .format(path)) if bentoml_config["kind"] != "BentoService": raise BentoMLException( "BentoArchive type '{}' can not be loaded as a BentoService". format(bentoml_config["kind"])) artifacts = ArtifactCollection.load(artifacts_path, cls._artifacts_spec) svc = cls(artifacts) return svc
def serve_gunicorn(port, workers, timeout, archive_path=archive_path, with_conda=False): if with_conda: config = load_bentoml_config(archive_path) metadata = config['metadata'] env_name = metadata['service_name'] + '_' + metadata[ 'service_version'] pip_req = os.path.join(archive_path, 'requirements.txt') subprocess.call( 'command -v conda >/dev/null 2>&1 || {{ echo >&2 "--with-conda ' 'parameter requires conda but it\'s not installed."; exit 1; }} && ' 'conda env update -n {env_name} -f {env_file} && ' 'conda init bash && ' 'eval "$(conda shell.bash hook)" && ' 'conda activate {env_name} && ' '{{ [ -f {pip_req} ] && pip install -r {pip_req} || echo "no pip ' 'dependencies."; }} &&' 'bentoml serve_gunicorn {archive_path} -p {port} -w {workers} ' '--timeout {timeout}'.format( env_name=env_name, env_file=os.path.join(archive_path, 'environment.yml'), archive_path=archive_path, port=port, workers=workers, timeout=timeout, pip_req=pip_req, ), shell=True, ) return track_cli('serve_gunicorn') from bentoml.server.gunicorn_server import GunicornBentoServer gunicorn_app = GunicornBentoServer(archive_path, port, workers, timeout) gunicorn_app.run()
def run(ctx, api_name, archive_path=archive_path, with_conda=False): if with_conda: config = load_bentoml_config(archive_path) metadata = config['metadata'] env_name = metadata['service_name'] + '_' + metadata[ 'service_version'] yaml = YAML() yaml.default_flow_style = False tmpf = tempfile.NamedTemporaryFile(delete=False) env_path = tmpf.name yaml.dump(config['env']['conda_env'], Path(env_path)) pip_req = os.path.join(archive_path, 'requirements.txt') subprocess.call( 'command -v conda >/dev/null 2>&1 || {{ echo >&2 "--with-conda ' 'parameter requires conda but it\'s not installed."; exit 1; }} && ' 'conda env update -n {env_name} -f {env_file} && ' 'conda init bash && ' 'eval "$(conda shell.bash hook)" && ' 'conda activate {env_name} && ' '{{ [ -f {pip_req} ] && pip install -r {pip_req} || echo "no pip ' 'dependencies."; }} &&' 'bentoml {api_name} {archive_path} {args}'.format( env_name=env_name, env_file=env_path, archive_path=archive_path, api_name=api_name, args=' '.join(map(escape_shell_params, ctx.args)), pip_req=pip_req, ), shell=True, ) return track_cli('run') api = load_service_api(archive_path, api_name) api.handle_cli(ctx.args)
def from_archive(cls, path): from bentoml.archive import load_bentoml_config if cls._bento_archive_path is not None and cls._bento_archive_path != path: raise BentoMLException( "Loaded BentoArchive(from {}) can't be loaded again from a different" "archive path {}".format(cls._bento_archive_path, path)) if is_s3_url(path): temporary_path = tempfile.mkdtemp() download_from_s3(path, temporary_path) # Use loacl temp path for the following loading operations path = temporary_path artifacts_path = path # For pip installed BentoService, artifacts directory is located at # 'package_path/artifacts/', but for loading from BentoArchive, it is # in 'path/{service_name}/artifacts/' if not os.path.isdir(os.path.join(path, "artifacts")): artifacts_path = os.path.join(path, cls.name()) bentoml_config = load_bentoml_config(path) if bentoml_config["metadata"]["service_name"] != cls.name(): raise BentoMLException( "BentoService name does not match with BentoArchive in path: {}" .format(path)) if bentoml_config["kind"] != "BentoService": raise BentoMLException( "BentoArchive type '{}' can not be loaded as a BentoService". format(bentoml_config["kind"])) artifacts = ArtifactCollection.load(artifacts_path, cls._artifacts_spec) svc = cls(artifacts) return svc