Skip to content

Commit 595a6ba

Browse files
authored
Merge branch 'dev' into pricing-update
2 parents cba2224 + 127c964 commit 595a6ba

File tree

10 files changed

+265
-15
lines changed

10 files changed

+265
-15
lines changed

CHANGELOG.md

+41-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,53 @@
11
# Changelog
22

3+
## v2.72.3 (2022-01-10)
4+
5+
### Features
6+
7+
* default repack encryption
8+
* support large pipeline
9+
* add support for pytorch 1.10.0
10+
11+
### Documentation Changes
12+
13+
* SageMaker model parallel library 1.6.0 API doc
14+
15+
### Bug Fixes and Other Changes
16+
17+
* Model Registration with BYO scripts
18+
* Add ContentType in test_auto_ml_describe
19+
* Re-deploy static integ test endpoint if it is not found
20+
* fix kmeans test deletion sequence, increment lineage statics
21+
* Increment static lineage pipeline
22+
* Fix lineage query integ tests
23+
* Add label_headers option for Clarify ModelExplainabilityMonitor
24+
* Add action type to lineage object
25+
* Collapse cross-account artifacts in query lineage response
26+
* Update CHANGELOG.md to remove defaulting dot characters
27+
28+
## v2.72.2 (2022-01-06)
29+
30+
### Bug Fixes and Other Changes
31+
32+
* Update CHANGELOG.md
33+
* Increment static lineage pipeline
34+
* fix kmeans test deletion sequence, increment lineage statics
35+
* Re-deploy static integ test endpoint if it is not found
36+
* Add ContentType in test_auto_ml_describe
37+
* Model Registration with BYO scripts
38+
39+
### Documentation Changes
40+
41+
* SageMaker model parallel library 1.6.0 API doc
42+
343
## v2.72.1 (2021-12-20)
444

545
### Bug Fixes and Other Changes
646

747
* typos and broken link
848
* S3Input - add support for instance attributes
949
* Prevent repack_model script from referencing nonexistent directories
10-
* Set ProcessingStep upload locations deterministically to avoid c…
50+
* Set ProcessingStep upload locations deterministically to avoid cache
1151

1252
## v2.72.0 (2021-12-13)
1353

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.72.2.dev0
1+
2.72.4.dev0

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def read_version():
104104
"Programming Language :: Python :: 3.6",
105105
"Programming Language :: Python :: 3.7",
106106
"Programming Language :: Python :: 3.8",
107+
"Programming Language :: Python :: 3.9",
107108
],
108109
install_requires=required_packages,
109110
extras_require=extras,

src/sagemaker/lineage/context.py

+49
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,55 @@ def models(self) -> List[association.Association]:
283283
]
284284
return model_list
285285

286+
def models_v2(
287+
self, direction: LineageQueryDirectionEnum = LineageQueryDirectionEnum.DESCENDANTS
288+
) -> List[Artifact]:
289+
"""Get artifacts representing models from the context lineage by querying lineage data.
290+
291+
Args:
292+
direction (LineageQueryDirectionEnum, optional): The query direction.
293+
294+
Returns:
295+
list of Artifacts: Artifacts representing a model.
296+
"""
297+
# Firstly query out the model_deployment vertices
298+
query_filter = LineageFilter(
299+
entities=[LineageEntityEnum.ACTION], sources=[LineageSourceEnum.MODEL_DEPLOYMENT]
300+
)
301+
model_deployment_query_result = LineageQuery(self.sagemaker_session).query(
302+
start_arns=[self.context_arn],
303+
query_filter=query_filter,
304+
direction=direction,
305+
include_edges=False,
306+
)
307+
if not model_deployment_query_result:
308+
return []
309+
310+
model_deployment_vertices: [] = model_deployment_query_result.vertices
311+
312+
# Secondary query model based on model deployment
313+
model_vertices = []
314+
for vertex in model_deployment_vertices:
315+
query_result = LineageQuery(self.sagemaker_session).query(
316+
start_arns=[vertex.arn],
317+
query_filter=LineageFilter(
318+
entities=[LineageEntityEnum.ARTIFACT], sources=[LineageSourceEnum.MODEL]
319+
),
320+
direction=LineageQueryDirectionEnum.DESCENDANTS,
321+
include_edges=False,
322+
)
323+
model_vertices.extend(query_result.vertices)
324+
325+
if not model_vertices:
326+
return []
327+
328+
model_artifacts = []
329+
for vertex in model_vertices:
330+
lineage_object = vertex.to_lineage_object()
331+
model_artifacts.append(lineage_object)
332+
333+
return model_artifacts
334+
286335
def dataset_artifacts(
287336
self, direction: LineageQueryDirectionEnum = LineageQueryDirectionEnum.ASCENDANTS
288337
) -> List[Artifact]:

src/sagemaker/workflow/lambda_step.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,6 @@ def _get_function_arn(self):
154154
Method creates a lambda function and returns it's arn.
155155
If the lambda is already present, it will build it's arn and return that.
156156
"""
157-
account_id = self.lambda_func.session.account_id()
158157
region = self.lambda_func.session.boto_region_name
159158
if region.lower() == "cn-north-1" or region.lower() == "cn-northwest-1":
160159
partition = "aws-cn"
@@ -163,6 +162,7 @@ def _get_function_arn(self):
163162

164163
if self.lambda_func.function_arn is None:
165164
try:
165+
account_id = self.lambda_func.session.account_id()
166166
response = self.lambda_func.create()
167167
return response["FunctionArn"]
168168
except ValueError as error:

tests/integ/sagemaker/lineage/conftest.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
from tests.integ.sagemaker.lineage.helpers import name, names
3737

3838
SLEEP_TIME_SECONDS = 1
39+
SLEEP_TIME_TWO_SECONDS = 2
3940
STATIC_PIPELINE_NAME = "SdkIntegTestStaticPipeline17"
4041
STATIC_ENDPOINT_NAME = "SdkIntegTestStaticEndpoint17"
4142

@@ -360,12 +361,10 @@ def endpoint_context_obj(sagemaker_session):
360361

361362
@pytest.fixture
362363
def model_obj(sagemaker_session):
363-
model = context.Context.create(
364-
context_name=name(),
364+
model = artifact.Artifact.create(
365+
artifact_name=name(),
366+
artifact_type="Model",
365367
source_uri="bar1",
366-
source_type="test-source-type1",
367-
context_type="Model",
368-
description="test-description",
369368
properties={"k1": "v1"},
370369
sagemaker_session=sagemaker_session,
371370
)
@@ -417,11 +416,12 @@ def endpoint_context_associate_with_model(sagemaker_session, endpoint_action_obj
417416

418417
association.Association.create(
419418
source_arn=endpoint_action_obj.action_arn,
420-
destination_arn=model_obj.context_arn,
419+
destination_arn=model_obj.artifact_arn,
421420
sagemaker_session=sagemaker_session,
422421
)
423422
yield obj
424-
time.sleep(SLEEP_TIME_SECONDS)
423+
# sleep 2 seconds since take longer for lineage injection
424+
time.sleep(SLEEP_TIME_TWO_SECONDS)
425425
obj.delete(disassociate=True)
426426

427427

tests/integ/sagemaker/lineage/test_endpoint_context.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,31 @@
1212
# language governing permissions and limitations under the License.
1313
"""This module contains code to test SageMaker ``Contexts``"""
1414
from __future__ import absolute_import
15+
import time
16+
17+
SLEEP_TIME_ONE_SECONDS = 1
1518

1619

1720
def test_model(endpoint_context_associate_with_model, model_obj, endpoint_action_obj):
1821
model_list = endpoint_context_associate_with_model.models()
1922
for model in model_list:
2023
assert model.source_arn == endpoint_action_obj.action_arn
21-
assert model.destination_arn == model_obj.context_arn
24+
assert model.destination_arn == model_obj.artifact_arn
2225
assert model.source_type == "ModelDeployment"
2326
assert model.destination_type == "Model"
2427

2528

29+
def test_model_v2(endpoint_context_associate_with_model, model_obj, sagemaker_session):
30+
time.sleep(SLEEP_TIME_ONE_SECONDS)
31+
model_list = endpoint_context_associate_with_model.models_v2()
32+
assert len(model_list) == 1
33+
for model in model_list:
34+
assert model.artifact_arn == model_obj.artifact_arn
35+
assert model.artifact_name == model_obj.artifact_name
36+
assert model.artifact_type == "Model"
37+
assert model.properties == model_obj.properties
38+
39+
2640
def test_dataset_artifacts(static_endpoint_context):
2741
artifacts_from_query = static_endpoint_context.dataset_artifacts()
2842

tests/unit/sagemaker/lineage/test_endpoint_context.py

+112
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import unittest.mock
1616

1717
from sagemaker.lineage import context, _api_types
18+
from sagemaker.lineage._api_types import ArtifactSource
19+
from sagemaker.lineage.artifact import ModelArtifact
1820

1921

2022
def test_models(sagemaker_session):
@@ -75,3 +77,113 @@ def test_models(sagemaker_session):
7577
)
7678
]
7779
assert expected_model_list == model_list
80+
81+
82+
def test_models_v2(sagemaker_session):
83+
arn1 = "arn:aws:sagemaker:us-west-2:123456789012:context/lineage-integ-3b05f017-0d87-4c37"
84+
85+
obj = context.EndpointContext(sagemaker_session, context_name="foo", context_arn=arn1)
86+
87+
sagemaker_session.sagemaker_client.query_lineage.return_value = {
88+
"Vertices": [
89+
{"Arn": arn1, "Type": "Model", "LineageType": "Artifact"},
90+
],
91+
"Edges": [{"SourceArn": "arn1", "DestinationArn": "arn2", "AssociationType": "Produced"}],
92+
}
93+
94+
sagemaker_session.sagemaker_client.describe_context.return_value = {
95+
"ContextName": "MyContext",
96+
"ContextArn": arn1,
97+
"Source": {
98+
"SourceUri": "arn:aws:sagemaker:us-west-2:0123456789012:endpoint/myendpoint",
99+
"SourceType": "ARN",
100+
"SourceId": "Thu Dec 17 17:16:24 UTC 2020",
101+
},
102+
"ContextType": "Endpoint",
103+
"Properties": {
104+
"PipelineExecutionArn": "arn:aws:sagemaker:us-west-2:0123456789012:\
105+
pipeline/mypipeline/execution/0irnteql64d0",
106+
"PipelineStepName": "MyStep",
107+
"Status": "Completed",
108+
},
109+
"CreationTime": 1608225384.0,
110+
"CreatedBy": {},
111+
"LastModifiedTime": 1608225384.0,
112+
"LastModifiedBy": {},
113+
}
114+
115+
sagemaker_session.sagemaker_client.describe_artifact.return_value = {
116+
"ArtifactName": "MyArtifact",
117+
"ArtifactArn": arn1,
118+
"Source": {
119+
"SourceUri": "arn:aws:sagemaker:us-west-2:0123456789012:model/mymodel",
120+
"SourceType": "ARN",
121+
"SourceId": "Thu Dec 17 17:16:24 UTC 2020",
122+
},
123+
"ArtifactType": "Model",
124+
"Properties": {
125+
"PipelineExecutionArn": "arn:aws:sagemaker:us-west-2:0123456789012:\
126+
pipeline/mypipeline/execution/0irnteql64d0",
127+
"PipelineStepName": "MyStep",
128+
"Status": "Completed",
129+
},
130+
"CreationTime": 1608225384.0,
131+
"CreatedBy": {},
132+
"LastModifiedTime": 1608225384.0,
133+
"LastModifiedBy": {},
134+
}
135+
136+
model_list = obj.models_v2()
137+
138+
expected_calls = [
139+
unittest.mock.call(
140+
Direction="Descendants",
141+
Filters={"Types": ["ModelDeployment"], "LineageTypes": ["Action"]},
142+
IncludeEdges=False,
143+
MaxDepth=10,
144+
StartArns=[arn1],
145+
),
146+
unittest.mock.call(
147+
Direction="Descendants",
148+
Filters={"Types": ["Model"], "LineageTypes": ["Artifact"]},
149+
IncludeEdges=False,
150+
MaxDepth=10,
151+
StartArns=[arn1],
152+
),
153+
]
154+
assert expected_calls == sagemaker_session.sagemaker_client.query_lineage.mock_calls
155+
156+
expected_model_list = [
157+
ModelArtifact(
158+
artifact_arn=arn1,
159+
artifact_name="MyArtifact",
160+
source=ArtifactSource(
161+
source_uri="arn:aws:sagemaker:us-west-2:0123456789012:model/mymodel",
162+
source_types=None,
163+
source_type="ARN",
164+
source_id="Thu Dec 17 17:16:24 UTC 2020",
165+
),
166+
artifact_type="Model",
167+
properties={
168+
"PipelineExecutionArn": "arn:aws:sagemaker:us-west-2:0123456789012:\
169+
pipeline/mypipeline/execution/0irnteql64d0",
170+
"PipelineStepName": "MyStep",
171+
"Status": "Completed",
172+
},
173+
creation_time=1608225384.0,
174+
created_by={},
175+
last_modified_time=1608225384.0,
176+
last_modified_by={},
177+
)
178+
]
179+
180+
assert expected_model_list[0].artifact_arn == model_list[0].artifact_arn
181+
assert expected_model_list[0].artifact_name == model_list[0].artifact_name
182+
assert expected_model_list[0].source == model_list[0].source
183+
assert expected_model_list[0].artifact_type == model_list[0].artifact_type
184+
assert expected_model_list[0].artifact_type == "Model"
185+
assert expected_model_list[0].properties == model_list[0].properties
186+
assert expected_model_list[0].creation_time == model_list[0].creation_time
187+
assert expected_model_list[0].created_by == model_list[0].created_by
188+
assert expected_model_list[0].last_modified_time == model_list[0].last_modified_time
189+
assert expected_model_list[0].last_modified_by == model_list[0].last_modified_by

tests/unit/sagemaker/workflow/test_lambda_step.py

+36-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import pytest
1818

19-
from mock import Mock
19+
from mock import Mock, MagicMock
2020

2121
from sagemaker.workflow.parameters import ParameterInteger, ParameterString
2222
from sagemaker.workflow.pipeline import Pipeline
@@ -27,12 +27,13 @@
2727
@pytest.fixture()
2828
def sagemaker_session():
2929
boto_mock = Mock(name="boto_session", region_name="us-west-2")
30-
session_mock = Mock(
30+
session_mock = MagicMock(
3131
name="sagemaker_session",
3232
boto_session=boto_mock,
3333
boto_region_name="us-west-2",
3434
config=None,
3535
local_mode=False,
36+
account_id=Mock(),
3637
)
3738
return session_mock
3839

@@ -173,3 +174,36 @@ def test_lambda_step_no_inputs_outputs(sagemaker_session):
173174
"OutputParameters": [],
174175
"Arguments": {},
175176
}
177+
178+
179+
def test_lambda_step_with_function_arn(sagemaker_session):
180+
lambda_step = LambdaStep(
181+
name="MyLambdaStep",
182+
depends_on=["TestStep"],
183+
lambda_func=Lambda(
184+
function_arn="arn:aws:lambda:us-west-2:123456789012:function:sagemaker_test_lambda",
185+
session=sagemaker_session,
186+
),
187+
inputs={},
188+
outputs=[],
189+
)
190+
lambda_step._get_function_arn()
191+
sagemaker_session.account_id.assert_not_called()
192+
193+
194+
def test_lambda_step_without_function_arn(sagemaker_session):
195+
lambda_step = LambdaStep(
196+
name="MyLambdaStep",
197+
depends_on=["TestStep"],
198+
lambda_func=Lambda(
199+
function_name="name",
200+
execution_role_arn="arn:aws:lambda:us-west-2:123456789012:execution_role",
201+
zipped_code_dir="",
202+
handler="",
203+
session=sagemaker_session,
204+
),
205+
inputs={},
206+
outputs=[],
207+
)
208+
lambda_step._get_function_arn()
209+
sagemaker_session.account_id.assert_called_once()

0 commit comments

Comments
 (0)