Skip to content

Commit 7823e8b

Browse files
authored
Merge branch 'master' into master
2 parents 05235c1 + 85056eb commit 7823e8b

File tree

6 files changed

+72
-7
lines changed

6 files changed

+72
-7
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Changelog
22

3+
## v2.244.0 (2025-05-02)
4+
5+
### Features
6+
7+
* support custom workflow deployment in ModelBuilder using SMD image.
8+
9+
### Bug Fixes and Other Changes
10+
11+
* Add Owner ID check for bucket with path when prefix is provided
12+
* Add model server timeout
13+
* pin mamba version to 24.11.3-2 to avoid inconsistent test runs
14+
* Update ModelTrainer to support s3 uri and tar.gz file as source_dir
15+
* chore: add huggingface images
16+
317
## v2.243.3 (2025-04-23)
418

519
### Bug Fixes and Other Changes

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.243.4.dev0
1+
2.244.1.dev0

src/sagemaker/session.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,6 @@ def _create_s3_bucket_if_it_does_not_exist(self, bucket_name, region):
635635

636636
elif self._default_bucket_set_by_sdk:
637637
self.general_bucket_check_if_user_has_permission(bucket_name, s3, bucket, region, False)
638-
639638
expected_bucket_owner_id = self.account_id()
640639
self.expected_bucket_owner_id_bucket_check(bucket_name, s3, expected_bucket_owner_id)
641640

@@ -649,9 +648,16 @@ def expected_bucket_owner_id_bucket_check(self, bucket_name, s3, expected_bucket
649648
650649
"""
651650
try:
652-
s3.meta.client.head_bucket(
653-
Bucket=bucket_name, ExpectedBucketOwner=expected_bucket_owner_id
654-
)
651+
if self.default_bucket_prefix:
652+
s3.meta.client.list_objects_v2(
653+
Bucket=bucket_name,
654+
Prefix=self.default_bucket_prefix,
655+
ExpectedBucketOwner=expected_bucket_owner_id,
656+
)
657+
else:
658+
s3.meta.client.head_bucket(
659+
Bucket=bucket_name, ExpectedBucketOwner=expected_bucket_owner_id
660+
)
655661
except ClientError as e:
656662
error_code = e.response["Error"]["Code"]
657663
message = e.response["Error"]["Message"]
@@ -682,7 +688,12 @@ def general_bucket_check_if_user_has_permission(
682688
bucket_creation_date_none (bool):Indicating whether S3 bucket already exists or not
683689
"""
684690
try:
685-
s3.meta.client.head_bucket(Bucket=bucket_name)
691+
if self.default_bucket_prefix:
692+
s3.meta.client.list_objects_v2(
693+
Bucket=bucket_name, Prefix=self.default_bucket_prefix
694+
)
695+
else:
696+
s3.meta.client.head_bucket(Bucket=bucket_name)
686697
except ClientError as e:
687698
error_code = e.response["Error"]["Code"]
688699
message = e.response["Error"]["Message"]

tests/integ/sagemaker/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
'SHELL ["/bin/bash", "-c"]\n'
4747
"RUN apt-get update -y \
4848
&& apt-get install -y unzip curl\n\n"
49-
"RUN curl -L -O 'https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh' \
49+
"RUN curl -L -O 'https://github.com/conda-forge/miniforge/releases/download/24.11.3-2/Miniforge3-Linux-x86_64.sh' \
5050
&& bash Miniforge3-Linux-x86_64.sh -b -p '/opt/conda' \
5151
&& /opt/conda/bin/conda init bash\n\n"
5252
"ENV PATH $PATH:/opt/conda/bin\n"

tests/integ/sagemaker/serve/test_serve_js_deep_unit_tests.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def test_js_model_with_optimize_speculative_decoding_config_gated_requests_are_e
6464
"Image": ANY,
6565
"Environment": {
6666
"SAGEMAKER_PROGRAM": "inference.py",
67+
"SAGEMAKER_MODEL_SERVER_TIMEOUT": "3600",
6768
"ENDPOINT_SERVER_TIMEOUT": "3600",
6869
"MODEL_CACHE_ROOT": "/opt/ml/model",
6970
"SAGEMAKER_ENV": "1",
@@ -150,6 +151,7 @@ def test_js_model_with_optimize_sharding_and_resource_requirements_requests_are_
150151
"Image": ANY,
151152
"Environment": {
152153
"SAGEMAKER_PROGRAM": "inference.py",
154+
"SAGEMAKER_MODEL_SERVER_TIMEOUT": "3600",
153155
"ENDPOINT_SERVER_TIMEOUT": "3600",
154156
"MODEL_CACHE_ROOT": "/opt/ml/model",
155157
"SAGEMAKER_ENV": "1",
@@ -237,6 +239,7 @@ def test_js_model_with_optimize_quantization_on_pre_optimized_model_requests_are
237239
"Image": ANY,
238240
"Environment": {
239241
"SAGEMAKER_PROGRAM": "inference.py",
242+
"SAGEMAKER_MODEL_SERVER_TIMEOUT": "3600",
240243
"ENDPOINT_SERVER_TIMEOUT": "3600",
241244
"MODEL_CACHE_ROOT": "/opt/ml/model",
242245
"SAGEMAKER_ENV": "1",

tests/unit/test_default_bucket.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ def sagemaker_session():
3939
return sagemaker_session
4040

4141

42+
@pytest.fixture()
43+
def sagemaker_session_with_bucket_name_and_prefix():
44+
boto_mock = MagicMock(name="boto_session", region_name=REGION)
45+
boto_mock.client("sts").get_caller_identity.return_value = {"Account": ACCOUNT_ID}
46+
sagemaker_session = sagemaker.Session(
47+
boto_session=boto_mock,
48+
default_bucket="XXXXXXXXXXXXX",
49+
default_bucket_prefix="sample-prefix",
50+
)
51+
sagemaker_session.boto_session.resource("s3").Bucket().creation_date = None
52+
return sagemaker_session
53+
54+
4255
def test_default_bucket_s3_create_call(sagemaker_session):
4356
error = ClientError(
4457
error_response={"Error": {"Code": "404", "Message": "Not Found"}},
@@ -96,6 +109,30 @@ def test_default_bucket_s3_needs_bucket_owner_access(sagemaker_session, datetime
96109
assert sagemaker_session._default_bucket is None
97110

98111

112+
def test_default_bucket_with_prefix_s3_needs_bucket_owner_access(
113+
sagemaker_session_with_bucket_name_and_prefix, datetime_obj, caplog
114+
):
115+
with pytest.raises(ClientError):
116+
error = ClientError(
117+
error_response={"Error": {"Code": "403", "Message": "Forbidden"}},
118+
operation_name="foo",
119+
)
120+
sagemaker_session_with_bucket_name_and_prefix.boto_session.resource(
121+
"s3"
122+
).meta.client.list_objects_v2.side_effect = error
123+
sagemaker_session_with_bucket_name_and_prefix.boto_session.resource("s3").Bucket(
124+
name=DEFAULT_BUCKET_NAME
125+
).creation_date = None
126+
sagemaker_session_with_bucket_name_and_prefix.default_bucket()
127+
128+
error_message = "Please try again after adding appropriate access."
129+
assert error_message in caplog.text
130+
assert sagemaker_session_with_bucket_name_and_prefix._default_bucket is None
131+
sagemaker_session_with_bucket_name_and_prefix.boto_session.resource(
132+
"s3"
133+
).meta.client.list_objects_v2.assert_called_once()
134+
135+
99136
def test_default_bucket_s3_custom_bucket_input(sagemaker_session, datetime_obj, caplog):
100137
sagemaker_session._default_bucket_name_override = "custom-bucket-override"
101138
error = ClientError(

0 commit comments

Comments
 (0)