The remote yatai client lists the model artifacts but fails to load them. Bentoml client works fine:
bentoml retrieve IrisClassifier:20210728102908_1CDF04 --target_dir $MYDIR
But is there a way to do this in python ideally predefining some env variables?
I know this can be done predefining boto3 python config but i'd like to skip S3 authentication with .aws/ directory
To Reproduce
from bentoml.yatai.client import get_yatai_client
remote_yatai_client = get_yatai_client('http://yatai:50051')
remote_yatai_client.repository.list()#.load('IrisClassifier:20210728102908_1CDF04')
[name: "IrisClassifier"
version: "20210728102908_1CDF04"
uri {
type: S3
uri: "s3://bentoml/artifacts/IrisClassifier/20210728102908_1CDF04.tar.gz"
}
bento_service_metadata {
name: "IrisClassifier"
version: "20210728102908_1CDF04"
created_at {
seconds: 1627460949
nanos: 518355000
}
env {
conda_env: "name: bentoml-default-conda-env\ndependencies: []\n"
python_version: "3.8.10"
docker_base_image: "bentoml/model-server:0.13.1-py38"
pip_packages: "bentoml==0.13.1"
pip_packages: "pandas==1.2.5"
pip_packages: "scikit-learn==0.24.2"
}
artifacts {
name: "model"
artifact_type: "SklearnModelArtifact"
metadata {
}
}
apis {
name: "predict"
input_type: "DataframeInput"
docs: "\n An inference API named `predict` with Dataframe input adapter, which codifies\n how HTTP requests or CSV files are converted to a pandas Dataframe object as the\n inference API function input\n "
input_config {
fields {
key: "dtype"
value {
null_value: NULL_VALUE
}
}
fields {
key: "orient"
value {
null_value: NULL_VALUE
}
}
fields {
key: "typ"
value {
string_value: "frame"
}
}
}
output_type: "DefaultOutput"
mb_max_latency: 20000
mb_max_batch_size: 4000
batch: true
route: "predict"
}
}
]
remote_yatai_client.repository.load('s3://bentoml/artifacts/IrisClassifier/20210728102908_1CDF04.tar.gz')
---------------------------------------------------------------------------
ClientError Traceback (most recent call last)
/tmp/ipykernel_175/710710685.py in <module>
----> 1 remote_yatai_client.repository.load('s3://bentoml/artifacts/IrisClassifier/20210728102908_1CDF04.tar.gz')
~/.local/lib/python3.8/site-packages/bentoml/yatai/client/bento_repository_api.py in load(self, bento)
683 else:
684 saved_bundle_path = resolve_bento_bundle_uri(bento_pb)
--> 685 svc = load_from_dir(saved_bundle_path)
686 return svc
687
~/.local/lib/python3.8/site-packages/bentoml/saved_bundle/loader.py in wrapper(bundle_path, *args)
105 def wrapper(bundle_path, *args):
106 if _is_remote_path(bundle_path):
--> 107 with _resolve_remote_bundle_path(bundle_path) as local_bundle_path:
108 return func(local_bundle_path, *args)
109
/opt/conda/envs/rapids/lib/python3.8/contextlib.py in __enter__(self)
111 del self.args, self.kwds, self.func
112 try:
--> 113 return next(self.gen)
114 except StopIteration:
115 raise RuntimeError("generator didn't yield") from None
~/.local/lib/python3.8/site-packages/bentoml/saved_bundle/loader.py in _resolve_remote_bundle_path(bundle_path)
62 s3 = boto3.client('s3')
63 fileobj = io.BytesIO()
---> 64 s3.download_fileobj(bucket_name, object_name, fileobj)
65 fileobj.seek(0, 0)
66 elif is_gcs_url(bundle_path):
/opt/conda/envs/rapids/lib/python3.8/site-packages/boto3/s3/inject.py in download_fileobj(self, Bucket, Key, Fileobj, ExtraArgs, Callback, Config)
676 bucket=Bucket, key=Key, fileobj=Fileobj,
677 extra_args=ExtraArgs, subscribers=subscribers)
--> 678 return future.result()
679
680
/opt/conda/envs/rapids/lib/python3.8/site-packages/s3transfer/futures.py in result(self)
104 # however if a KeyboardInterrupt is raised we want want to exit
105 # out of this and propogate the exception.
--> 106 return self._coordinator.result()
107 except KeyboardInterrupt as e:
108 self.cancel()
/opt/conda/envs/rapids/lib/python3.8/site-packages/s3transfer/futures.py in result(self)
263 # final result.
264 if self._exception:
--> 265 raise self._exception
266 return self._result
267
/opt/conda/envs/rapids/lib/python3.8/site-packages/s3transfer/tasks.py in _main(self, transfer_future, **kwargs)
253 # Call the submit method to start submitting tasks to execute the
254 # transfer.
--> 255 self._submit(transfer_future=transfer_future, **kwargs)
256 except BaseException as e:
257 # If there was an exception raised during the submission of task
/opt/conda/envs/rapids/lib/python3.8/site-packages/s3transfer/download.py in _submit(self, client, config, osutil, request_executor, io_executor, transfer_future, bandwidth_limiter)
338 # If a size was not provided figure out the size for the
339 # user.
--> 340 response = client.head_object(
341 Bucket=transfer_future.meta.call_args.bucket,
342 Key=transfer_future.meta.call_args.key,
/opt/conda/envs/rapids/lib/python3.8/site-packages/botocore/client.py in _api_call(self, *args, **kwargs)
384 "%s() only accepts keyword arguments." % py_operation_name)
385 # The "self" in this scope is referring to the BaseClient.
--> 386 return self._make_api_call(operation_name, kwargs)
387
388 _api_call.__name__ = str(py_operation_name)
/opt/conda/envs/rapids/lib/python3.8/site-packages/botocore/client.py in _make_api_call(self, operation_name, api_params)
703 error_code = parsed_response.get("Error", {}).get("Code")
704 error_class = self.exceptions.from_code(error_code)
--> 705 raise error_class(parsed_response, operation_name)
706 else:
707 return parsed_response
ClientError: An error occurred (403) when calling the HeadObject operation: Forbidden
Describe the bug
The remote yatai client lists the model artifacts but fails to load them. Bentoml client works fine:
bentoml retrieve IrisClassifier:20210728102908_1CDF04 --target_dir $MYDIR
But is there a way to do this in python ideally predefining some env variables? I know this can be done predefining boto3 python config but i'd like to skip S3 authentication with .aws/ directory
To Reproduce
Expected behavior
Screenshots/Logs
Environment:
Additional context