def serve(port, archive_path=installed_archive_path): """ Start REST API server hosting BentoService loaded from archive """ model_service = load(archive_path) server = BentoAPIServer(model_service, port=port) server.start()
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 serve_gunicorn(port, workers, archive_path=installed_archive_path): """ Start REST API gunicorn server hosting BentoService loaded from archive """ model_service = load(archive_path) server = BentoAPIServer(model_service, port=port) gunicorn_app = GunicornApplication(server.app, port, workers) gunicorn_app.run()
def info(archive_path=installed_archive_path): """ List all APIs definied in the BentoService loaded from archive """ model_service = load(archive_path) service_apis = model_service.get_service_apis() output = json.dumps( dict(name=model_service.name, version=model_service.version, apis=[api.name for api in service_apis]), indent=2) print(output)
def build_serverless_archive(ctx, archive_path, output_path, platform): if which('serverless') is None: click.echo('Serverless framework is not installed', err=True) click.echo('Please visit www.serverless.com for install instructions') return bento_service = load(archive_path) generate_serverless_bundle(bento_service, platform, archive_path, output_path, ctx.args) click.echo('BentoML: ', nl=False) click.secho('Build serverless archive complete!', fg='green') return
def run(ctx, api_name, archive_path=archive_path): model_service = load(archive_path) try: api = next((api for api in model_service.get_service_apis() if api.name == api_name)) except StopIteration: raise ValueError("Can't find API '{}' in Service '{}'".format( api_name, model_service.name)) api.handle_cli(ctx.args)
def run(ctx, api_name, archive_path=installed_archive_path): """ Run an API definied in the BentoService loaded from archive """ model_service = load(archive_path) try: api = next((api for api in model_service.get_service_apis() if api.name == api_name)) except StopIteration: raise ValueError("Can't find API '{}' in Service '{}'".format( api_name, model_service.name)) api.handle_cli(ctx.args)
def info(archive_path=archive_path): """ List all APIs defined in the BentoService loaded from archive """ track_cli('info') bento_service = load(archive_path) service_apis = bento_service.get_service_apis() output = json.dumps( dict( name=bento_service.name, version=bento_service.version, apis=[api.name for api in service_apis], ), indent=2, ) _echo(output)
def deploy_with_serverless(platform, archive_path, extra_args): bento_service = load(archive_path) output_path = generate_serverless_bundle(bento_service, platform, archive_path, extra_args) subprocess.call(['serverless', 'deploy'], cwd=output_path) return output_path
def deploy_bentoml( clipper_conn, archive_path, api_name, input_type="strings", model_name=None, labels=None, ): """Deploy bentoml bundle to clipper cluster Args: clipper_conn(clipper_admin.ClipperConnection): Clipper connection instance archive_path(str): Path to the bentoml service archive. api_name(str): name of the api that will be used as prediction function for clipper cluster input_type(str): Input type that clipper accept. The default input_type for image handler is `bytes`, for other handlers is `strings`. Availabel input_type are `integers`, `floats`, `doubles`, `bytes`, or `strings` model_name(str): Model's name for clipper cluster labels(:obj:`list(str)`, optional): labels for clipper model Returns: tuple: Model name and model version that deployed to clipper """ bento_service = load(archive_path) api = bento_service.get_service_api(api_name) model_name = model_name or generate_clipper_compatiable_string( bento_service.name + "-" + api.name) version = generate_clipper_compatiable_string(bento_service.version) if isinstance(api.handler, ImageHandler): input_type = "bytes" try: clipper_conn.start_clipper() except docker.errors.APIError: clipper_conn.connect() except Exception: raise BentoMLException("Can't start or connect with clipper cluster") snapshot_path = generate_clipper_deployment_snapshot_path( bento_service.name, bento_service.version) entry_py_content = DEFAULT_CLIPPER_ENTRY.format(api_name=api.name, input_type=input_type) model_path = os.path.join(snapshot_path, "bento") shutil.copytree(archive_path, model_path) with open(os.path.join(snapshot_path, "clipper_entry.py"), "w") as f: f.write(entry_py_content) docker_content = DOCKERFILE_CLIPPER.format(model_name=model_name, model_version=version) with open(os.path.join(snapshot_path, "Dockerfile-clipper"), "w") as f: f.write(docker_content) docker_api = docker.APIClient() image_tag = bento_service.name.lower( ) + "-clipper:" + bento_service.version for line in docker_api.build(path=snapshot_path, dockerfile="Dockerfile-clipper", tag=image_tag): process_docker_api_line(line) clipper_conn.deploy_model( name=model_name, version=version, input_type=input_type, image=image_tag, labels=labels, ) return model_name, version
def load(): return archive.load(__module_path)
def docs(archive_path=archive_path): model_service = load(archive_path) print(json.dumps(get_docs(model_service), indent=2))
def load(self): from bentoml import archive self._bento_service = archive.load(self._bento_service_class, self._path) self._wrap_api_funcs() self.loaded = True
def serve(port, archive_path=archive_path): model_service = load(archive_path) server = BentoAPIServer(model_service, port=port) server.start()
def open_api_spec(archive_path=archive_path): track_cli('open-api-spec') bento_service = load(archive_path) _echo(json.dumps(get_docs(bento_service), indent=2))
def load(self): bento_service = load(self.bento_archive_path) api_server = BentoAPIServer(bento_service, port=self.port) return api_server.app
def __init__(self, archive_path): self.bento_service = load(archive_path) self.archive_path = archive_path
def serve_gunicorn(port, workers, timeout, archive_path=archive_path): model_service = load(archive_path) server = BentoAPIServer(model_service, port=port) gunicorn_app = GunicornApplication(server.app, port, workers, timeout) gunicorn_app.run()
def docs(archive_path=archive_path): track_cli('docs') bento_service = load(archive_path) _echo(json.dumps(get_docs(bento_service), indent=2))
def serve(port, archive_path=archive_path): track_cli('serve') bento_service = load(archive_path) server = BentoAPIServer(bento_service, port=port) server.start()