Repository navigation
feat: hub search and metadata, trainer job handles, typed deploy options, endpoint diagnostics, Bedrock and S3 helpers #6533
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
450c866
6e9df41
c2db676
d352fe5
8c8dd9a
b04f4c9
b6959d8
93c0a67
097192a
fb7c616
a4c2786
5a134b9
2c09cf5
cd59491
41aae12
d906911
6e820f6
0727c47
c6294e1
4c9bedb
4b89520
a20a1e6
326e8bd
76c02cd
fa28a67
7ffd898
cb1a6ea
8f9ea7f
f529db2
625a4f0
a081545
4042f61
5ea7b09
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1688,12 +1688,53 @@ def create_paginator_config(max_items: int = None, page_size: int = None) -> Dic | |
| } | ||
|
|
||
|
|
||
| def _normalize_tag(tag: Any) -> TagsDict: | ||
| """Return one tag as a boto-style ``{"Key": ..., "Value": ...}`` dict. | ||
|
|
||
| Accepts the boto form, the ``{"key": ..., "value": ...}`` form that the | ||
| ``sagemaker.core.resources`` classes take, and a ``Tag`` shape object (anything | ||
| with ``key`` and ``value`` attributes). Any other input raises ``TypeError`` so a | ||
| malformed tag fails at the call site instead of as a ``KeyError`` deep in a | ||
| deploy path. | ||
| """ | ||
| if isinstance(tag, dict): | ||
| if "Key" in tag: | ||
| return {"Key": tag["Key"], "Value": tag.get("Value")} | ||
| if "key" in tag: | ||
| return {"Key": tag["key"], "Value": tag.get("value")} | ||
| raise TypeError( | ||
| "A tag dict must have a 'Key' (or 'key') entry, " | ||
| f"got {sorted(tag)}. Pass a {{key: value}} mapping to set many tags at once." | ||
| ) | ||
| if hasattr(tag, "key") and hasattr(tag, "value"): | ||
| return {"Key": tag.key, "Value": tag.value} | ||
| raise TypeError( | ||
| "A tag must be a {'Key': ..., 'Value': ...} dict, a {'key': ..., 'value': ...} dict, " | ||
| f"or a Tag object, got {type(tag).__name__}." | ||
| ) | ||
|
|
||
|
|
||
| def format_tags(tags: Tags) -> List[TagsDict]: | ||
| """Process tags to turn them into the expected format for Sagemaker.""" | ||
| """Process tags to turn them into the expected format for Sagemaker. | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Low: |
||
| Every accepted representation comes out as a list of boto-style | ||
| ``{"Key": ..., "Value": ...}`` dicts: | ||
|
|
||
| * a ``{key: value}`` mapping, one tag per entry; | ||
| * a single tag dict or ``Tag`` object; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Low:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Every representation now comes out with |
||
| * a list of tag dicts in either casing, ``Tag`` objects, or a mix. | ||
|
|
||
| ``None`` is returned unchanged. | ||
| """ | ||
| if tags is None: | ||
| return tags | ||
| if isinstance(tags, dict): | ||
| if "Key" in tags or "key" in tags: | ||
| return [_normalize_tag(tags)] | ||
| return [{"Key": str(k), "Value": str(v)} for k, v in tags.items()] | ||
|
|
||
| return tags | ||
| if isinstance(tags, (list, tuple)): | ||
| return [_normalize_tag(tag) for tag in tags] | ||
| return [_normalize_tag(tags)] | ||
|
|
||
|
|
||
| def _get_resolved_path(path): | ||
|
|
@@ -2124,8 +2165,9 @@ def tag_exists(tag: TagsDict, curr_tags: Optional[Tags]) -> bool: | |
| if curr_tags is None: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Low: |
||
| return False | ||
|
|
||
| for curr_tag in curr_tags: | ||
| if tag["Key"] == curr_tag["Key"]: | ||
| key = _normalize_tag(tag)["Key"] | ||
| for curr_tag in format_tags(curr_tags): | ||
| if key == curr_tag["Key"]: | ||
| return True | ||
|
|
||
| return False | ||
|
|
@@ -2141,21 +2183,18 @@ def _validate_new_tags(new_tags: Optional[Tags], curr_tags: Optional[Tags]) -> O | |
| Returns: | ||
| Optional[Tags]: The updated tags. | ||
| """ | ||
| if curr_tags is None: | ||
| return new_tags | ||
| if new_tags is None: | ||
| return format_tags(curr_tags) if curr_tags is not None else None | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Low:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Confirmed: |
||
|
|
||
| if curr_tags and isinstance(curr_tags, dict): | ||
| curr_tags = [curr_tags] | ||
| if curr_tags is None: | ||
| return format_tags(new_tags) | ||
|
|
||
| if isinstance(new_tags, dict): | ||
| if not tag_exists(new_tags, curr_tags): | ||
| curr_tags.append(new_tags) | ||
| elif isinstance(new_tags, list): | ||
| for new_tag in new_tags: | ||
| if not tag_exists(new_tag, curr_tags): | ||
| curr_tags.append(new_tag) | ||
| merged = format_tags(curr_tags) | ||
| for new_tag in format_tags(new_tags): | ||
| if not tag_exists(new_tag, merged): | ||
| merged.append(new_tag) | ||
|
|
||
| return curr_tags | ||
| return merged | ||
|
|
||
|
|
||
| def remove_tag_with_key(key: str, tags: Optional[Tags]) -> Optional[Tags]: | ||
|
|
@@ -2170,11 +2209,9 @@ def remove_tag_with_key(key: str, tags: Optional[Tags]) -> Optional[Tags]: | |
| """ | ||
| if tags is None: | ||
| return tags | ||
| if isinstance(tags, dict): | ||
| tags = [tags] | ||
|
|
||
| updated_tags = [] | ||
| for tag in tags: | ||
| for tag in format_tags(tags): | ||
| if tag["Key"] != key: | ||
| updated_tags.append(tag) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 Low:
format_tagsis annotated-> List[TagsDict]but now returnsNoneunchanged whentags is None. ConsiderOptional[List[TagsDict]]to match the actual contract (several callers like_deploy_recommendationrely on theNonepassthrough).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to
Optional[List[TagsDict]], withOptional[Tags]on the parameter. Commit a20a1e6.