Skip to content

Commit 67e8d94

Browse files
rubanhRuban Hussain
andcommitted
intelligent defaults - custom parameters and small fixes (aws#845)
* fix: sagemaker-config - S3 session, tuning tags, config schema test side-effects * feature: sagemaker-config - support for custom parameters in config schema --------- Co-authored-by: Ruban Hussain <[email protected]>
1 parent 6c9bc6a commit 67e8d94

File tree

4 files changed

+57
-28
lines changed

4 files changed

+57
-28
lines changed

src/sagemaker/config/config_schema.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,11 @@
7070
ENDPOINT_CONFIG = "EndpointConfig"
7171
AUTO_ML = "AutoML"
7272
COMPILATION_JOB = "CompilationJob"
73+
CUSTOM_PARAMETERS = "CustomParameters"
7374
PIPELINE = "Pipeline"
7475
TRANSFORM_JOB = "TransformJob"
7576
PROPERTIES = "properties"
77+
PATTERN_PROPERTIES = "patternProperties"
7678
TYPE = "type"
7779
OBJECT = "object"
7880
ADDITIONAL_PROPERTIES = "additionalProperties"
@@ -104,7 +106,6 @@ def _simple_path(*args: str):
104106
SAGEMAKER, TRAINING_JOB, ENABLE_INTER_CONTAINER_TRAFFIC_ENCRYPTION
105107
)
106108

107-
108109
SAGEMAKER_PYTHON_SDK_CONFIG_SCHEMA = {
109110
"$schema": "https://json-schema.org/draft/2020-12/schema",
110111
TYPE: OBJECT,
@@ -231,6 +232,13 @@ def _simple_path(*args: str):
231232
"enum": ["1.0"],
232233
"description": "The schema version of the document.",
233234
},
235+
CUSTOM_PARAMETERS: {
236+
TYPE: OBJECT,
237+
ADDITIONAL_PROPERTIES: False,
238+
PATTERN_PROPERTIES: {
239+
"^[\w\s\d_.:/=+\-@]+$": {TYPE: "string"},
240+
}
241+
},
234242
SAGEMAKER: {
235243
TYPE: OBJECT,
236244
ADDITIONAL_PROPERTIES: False,

src/sagemaker/session.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
ENDPOINT_CONFIG,
4242
FEATURE_GROUP,
4343
KEY,
44-
HYPER_PARAMETER_TUNING_JOB,
4544
SAGEMAKER,
4645
MODEL,
4746
MONITORING_SCHEDULE,
@@ -219,7 +218,7 @@ def _initialize(
219218
if sagemaker_config:
220219
self.sagemaker_config = sagemaker_config
221220
else:
222-
self.sagemaker_config = SageMakerConfig(s3_resource=self.boto_session)
221+
self.sagemaker_config = SageMakerConfig(s3_resource=self.boto_session.resource("s3"))
223222

224223
@property
225224
def boto_region_name(self):
@@ -2642,9 +2641,6 @@ def tune( # noqa: C901
26422641
tune_request["WarmStartConfig"] = warm_start_config
26432642

26442643
tags = _append_project_tags(tags)
2645-
tags = self._append_sagemaker_config_tags(
2646-
tags, "{}.{}.{}".format(SAGEMAKER, HYPER_PARAMETER_TUNING_JOB, TAGS)
2647-
)
26482644
if tags is not None:
26492645
tune_request["Tags"] = tags
26502646

@@ -2747,9 +2743,6 @@ def _get_tuning_request(
27472743
tune_request["WarmStartConfig"] = warm_start_config
27482744

27492745
tags = _append_project_tags(tags)
2750-
tags = self._append_sagemaker_config_tags(
2751-
tags, "{}.{}.{}".format(SAGEMAKER, HYPER_PARAMETER_TUNING_JOB, TAGS)
2752-
)
27532746
if tags is not None:
27542747
tune_request["Tags"] = tags
27552748

tests/unit/sagemaker/config/conftest.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,22 @@
1717
from mock import MagicMock
1818

1919

20-
@pytest.fixture(scope="module")
20+
@pytest.fixture()
2121
def base_config_with_schema():
2222
return {"SchemaVersion": "1.0"}
2323

2424

25-
@pytest.fixture(scope="module")
25+
@pytest.fixture()
2626
def valid_vpc_config():
2727
return {"SecurityGroupIds": ["sg123"], "Subnets": ["subnet-1234"]}
2828

2929

30-
@pytest.fixture(scope="module")
30+
@pytest.fixture()
3131
def valid_iam_role_arn():
3232
return "arn:aws:iam::366666666666:role/IMRole"
3333

3434

35-
@pytest.fixture(scope="module")
35+
@pytest.fixture()
3636
def valid_feature_group_config(valid_iam_role_arn):
3737
s3_storage_config = {"KmsKeyId": "somekmskeyid"}
3838
security_storage_config = {"KmsKeyId": "someotherkmskeyid"}
@@ -45,15 +45,15 @@ def valid_feature_group_config(valid_iam_role_arn):
4545
}
4646

4747

48-
@pytest.fixture(scope="module")
48+
@pytest.fixture()
4949
def valid_edge_packaging_config(valid_iam_role_arn):
5050
return {
5151
"OutputConfig": {"KmsKeyId": "somekeyid"},
5252
"RoleArn": valid_iam_role_arn,
5353
}
5454

5555

56-
@pytest.fixture(scope="module")
56+
@pytest.fixture()
5757
def valid_model_config(valid_iam_role_arn, valid_vpc_config):
5858
return {
5959
"EnableNetworkIsolation": True,
@@ -62,7 +62,7 @@ def valid_model_config(valid_iam_role_arn, valid_vpc_config):
6262
}
6363

6464

65-
@pytest.fixture(scope="module")
65+
@pytest.fixture()
6666
def valid_model_package_config(valid_iam_role_arn):
6767
transform_job_definition = {
6868
"TransformOutput": {"KmsKeyId": "somerandomkmskeyid"},
@@ -75,7 +75,7 @@ def valid_model_package_config(valid_iam_role_arn):
7575
return {"ValidationSpecification": validation_specification}
7676

7777

78-
@pytest.fixture(scope="module")
78+
@pytest.fixture()
7979
def valid_processing_job_config(valid_iam_role_arn, valid_vpc_config):
8080
network_config = {"EnableNetworkIsolation": True, "VpcConfig": valid_vpc_config}
8181
dataset_definition = {
@@ -94,7 +94,7 @@ def valid_processing_job_config(valid_iam_role_arn, valid_vpc_config):
9494
}
9595

9696

97-
@pytest.fixture(scope="module")
97+
@pytest.fixture()
9898
def valid_training_job_config(valid_iam_role_arn, valid_vpc_config):
9999
return {
100100
"EnableNetworkIsolation": True,
@@ -105,12 +105,12 @@ def valid_training_job_config(valid_iam_role_arn, valid_vpc_config):
105105
}
106106

107107

108-
@pytest.fixture(scope="module")
108+
@pytest.fixture()
109109
def valid_pipeline_config(valid_iam_role_arn):
110110
return {"RoleArn": valid_iam_role_arn}
111111

112112

113-
@pytest.fixture(scope="module")
113+
@pytest.fixture()
114114
def valid_compilation_job_config(valid_iam_role_arn, valid_vpc_config):
115115
return {
116116
"OutputConfig": {"KmsKeyId": "somekmskey"},
@@ -119,7 +119,7 @@ def valid_compilation_job_config(valid_iam_role_arn, valid_vpc_config):
119119
}
120120

121121

122-
@pytest.fixture(scope="module")
122+
@pytest.fixture()
123123
def valid_transform_job_config():
124124
return {
125125
"DataCaptureConfig": {"KmsKeyId": "somekmskey"},
@@ -128,7 +128,7 @@ def valid_transform_job_config():
128128
}
129129

130130

131-
@pytest.fixture(scope="module")
131+
@pytest.fixture()
132132
def valid_automl_config(valid_iam_role_arn, valid_vpc_config):
133133
return {
134134
"AutoMLJobConfig": {
@@ -139,7 +139,7 @@ def valid_automl_config(valid_iam_role_arn, valid_vpc_config):
139139
}
140140

141141

142-
@pytest.fixture(scope="module")
142+
@pytest.fixture()
143143
def valid_endpointconfig_config():
144144
return {
145145
"AsyncInferenceConfig": {"OutputConfig": {"KmsKeyId": "somekmskey"}},
@@ -150,7 +150,7 @@ def valid_endpointconfig_config():
150150
}
151151

152152

153-
@pytest.fixture(scope="module")
153+
@pytest.fixture()
154154
def valid_monitoring_schedule_config(valid_iam_role_arn, valid_vpc_config):
155155
network_config = {"EnableNetworkIsolation": True, "VpcConfig": valid_vpc_config}
156156
return {
@@ -165,7 +165,7 @@ def valid_monitoring_schedule_config(valid_iam_role_arn, valid_vpc_config):
165165
}
166166

167167

168-
@pytest.fixture(scope="module")
168+
@pytest.fixture()
169169
def valid_config_with_all_the_scopes(
170170
valid_feature_group_config,
171171
valid_monitoring_schedule_config,
@@ -196,11 +196,11 @@ def valid_config_with_all_the_scopes(
196196
}
197197

198198

199-
@pytest.fixture(scope="module")
199+
@pytest.fixture()
200200
def s3_resource_mock():
201201
return MagicMock(name="s3")
202202

203203

204-
@pytest.fixture(scope="module")
204+
@pytest.fixture()
205205
def get_data_dir():
206206
return os.path.join(os.path.dirname(__file__), "..", "..", "..", "data", "config")

tests/unit/sagemaker/config/test_config_schema.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def test_invalid_schema_version():
3838

3939

4040
def test_valid_config_with_all_the_features(
41-
base_config_with_schema, valid_config_with_all_the_scopes
41+
base_config_with_schema, valid_config_with_all_the_scopes
4242
):
4343
_validate_config(base_config_with_schema, valid_config_with_all_the_scopes)
4444

@@ -137,3 +137,31 @@ def test_invalid_feature_group_schema(base_config_with_schema):
137137
config["SageMaker"] = {"FeatureGroup": feature_group_config}
138138
with pytest.raises(exceptions.ValidationError):
139139
validate(config, SAGEMAKER_PYTHON_SDK_CONFIG_SCHEMA)
140+
141+
142+
def test_valid_custom_parameters_schema(base_config_with_schema):
143+
config = base_config_with_schema
144+
config["CustomParameters"] = {
145+
"custom_key": "custom_value",
146+
"CustomKey": "CustomValue",
147+
"custom key": "custom value",
148+
"custom-key": "custom-value",
149+
"custom0123 key0123": "custom0123 value0123",
150+
}
151+
validate(config, SAGEMAKER_PYTHON_SDK_CONFIG_SCHEMA)
152+
153+
154+
def test_invalid_custom_parameters_schema(base_config_with_schema):
155+
config = base_config_with_schema
156+
157+
config["CustomParameters"] = {"^&": "custom_value"}
158+
with pytest.raises(exceptions.ValidationError):
159+
validate(config, SAGEMAKER_PYTHON_SDK_CONFIG_SCHEMA)
160+
161+
config["CustomParameters"] = {"custom_key": 476}
162+
with pytest.raises(exceptions.ValidationError):
163+
validate(config, SAGEMAKER_PYTHON_SDK_CONFIG_SCHEMA)
164+
165+
config["CustomParameters"] = {"custom_key": {"custom_key": "custom_value"}}
166+
with pytest.raises(exceptions.ValidationError):
167+
validate(config, SAGEMAKER_PYTHON_SDK_CONFIG_SCHEMA)

0 commit comments

Comments
 (0)