Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
13 changes: 13 additions & 0 deletions .pydocstylerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# pydocstyle configuration shared by all four submodules. Each submodule's tox
# ``docstyle`` env runs ``pydocstyle src/sagemaker`` from the submodule root;
# pydocstyle walks up from the checked files and picks this file up.
#
# Restored from the v2 (master-v2) branch, where it lived at the repo root and
# was lost in the v3 monorepo split. The generated API surface
# (``sagemaker/core/resources.py`` and ``sagemaker/core/shapes/shapes.py``)
# is excluded: it is produced by the code generator, not hand-written.
[pydocstyle]
inherit = false
ignore = D104,D107,D202,D203,D213,D214,D400,D401,D404,D406,D407,D411,D413,D414,D415,D417
match = (?!record_pb2)(?!resources\.py$)(?!shapes\.py$).*\.py
match-dir = (?!.*test).*
21 changes: 18 additions & 3 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ ignore=CVS,tensorflow_serving
ignore-patterns=
.*_pb2.py, # Ignore all files generated by the protocol buffer compiler

# Add files or directories matching the regex patterns to the ignore list. The
# regex matches against paths and can be comma(and newline)-separated. Use
# forward slashes and ``[.]`` rather than ``\.``: pylint rewrites backslashes to
# build the Windows variant of each pattern. The sagemaker-core API surface
# below is emitted by the code generator and is not hand-maintained, so it is
# not linted.
ignore-paths=
^.*/sagemaker/core/resources[.]py$,
^.*/sagemaker/core/shapes/shapes[.]py$

# Pickle collected data for later comparisons.
persistent=yes

Expand Down Expand Up @@ -109,9 +119,12 @@ disable=
W0237, # Argument renamed in override
W0613, # Unused argument
W0621, # Redefining name from outer scope
W0719
W0718, # Broad exception caught: the SDK deliberately catches Exception at many boundaries
W0719, # Broad exception raised
W1203, # Logging f-string interpolation: the v3 code base uses f-strings in log calls throughout
W1404, # Implicit string concatenation
W1514, # `open()` used without encoding
R0801, # Duplicate code: the v3 split intentionally mirrors helpers across submodules

[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
Expand Down Expand Up @@ -245,8 +258,10 @@ bad-functions=
max-nested-blocks=5

[FORMAT]
# Maximum number of characters on a single line.
max-line-length=100
# Maximum number of characters on a single line. Black formats to 100 but will
# not split long strings and comments; flake8 (tox.ini) accepts 120 for the same
# reason, so pylint is aligned with it rather than flagging black's output.
max-line-length=120

# Regexp for a line that is allowed to be longer than the limit. Can only be a single regex.
# The following matches any semblance of a url of any sort.
Expand Down
2 changes: 1 addition & 1 deletion sagemaker-core/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ SageMaker Core
Introduction
------------

Welcome to the sagemaker-core Python SDK, an SDK designed to provide an object-oriented interface for interacting with Amazon SageMaker resources. It offers full parity with SageMaker APIs, allowing developers to leverage all SageMaker capabilities directly through the SDK. sagemaker-core introduces features such as dedicated resource classes, resource chaining, auto code completion, comprehensive documentation and type hints to enhance the developer experience as well as productivity.
Welcome to the sagemaker-core Python SDK, an SDK designed to provide an object-oriented interface for interacting with Amazon SageMaker resources. It offers full parity with SageMaker APIs, allowing developers to leverage all SageMaker capabilities directly through the SDK. sagemaker-core introduces features such as dedicated resource classes, resource chaining, auto code completion, comprehensive documentation and type hints to enhance the developer experience as well as productivity.


Key Features
Expand Down
2 changes: 1 addition & 1 deletion sagemaker-core/docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ SageMaker Core Shapes

.. automodule:: sagemaker.core.shapes
:members:
:noindex:
:noindex:
2 changes: 1 addition & 1 deletion sagemaker-core/docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
sphinx==7.4.7
sphinx-rtd-theme==2.0.0
sphinx-rtd-theme==2.0.0
4 changes: 3 additions & 1 deletion sagemaker-core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ namespaces = true

[tool.black]
line-length = 100
exclude = '\.ipynb$'
# ``exclude`` would replace black's default exclusions (.tox, .git, build, ...),
# which made the CI black-check env scan its own .tox tree.
extend-exclude = '\.ipynb$'

[tool.setuptools.dynamic]
version = { attr = "sagemaker.core._version.__version__"}
Expand Down
11 changes: 5 additions & 6 deletions sagemaker-core/src/sagemaker/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from sagemaker.core.utils.utils import enable_textual_rich_console_and_traceback
from sagemaker.core.deprecations import register_removed_module_finder


enable_textual_rich_console_and_traceback()

# Install the meta-path finder that gives actionable migration guidance for v2
Expand All @@ -14,19 +13,19 @@
register_removed_module_finder()

# Job management
from sagemaker.core.job import _Job # noqa: F401
from sagemaker.core.processing import ( # noqa: F401
from sagemaker.core.job import _Job # noqa: F401, E402
from sagemaker.core.processing import ( # noqa: F401, E402
Processor,
ScriptProcessor,
FrameworkProcessor,
)
from sagemaker.core.transformer import Transformer # noqa: F401
from sagemaker.core.transformer import Transformer # noqa: F401, E402

# Partner App
from sagemaker.core.partner_app.auth_provider import PartnerAppAuthProvider # noqa: F401
from sagemaker.core.partner_app.auth_provider import PartnerAppAuthProvider # noqa: F401, E402

# Attribution
from sagemaker.core.telemetry.attribution import Attribution, set_attribution # noqa: F401
from sagemaker.core.telemetry.attribution import Attribution, set_attribution # noqa: F401, E402

# Note: HyperparameterTuner and WarmStartTypes are in sagemaker.train.tuner
# They are not re-exported from core to avoid circular dependencies
1 change: 1 addition & 0 deletions sagemaker-core/src/sagemaker/core/_studio.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
"""Provides internal tooling for studio environments."""

from __future__ import absolute_import

import json
Expand Down
1 change: 1 addition & 0 deletions sagemaker-core/src/sagemaker/core/accept_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
"""This module is for SageMaker accept types."""

from __future__ import absolute_import
from typing import List, Optional

Expand Down
1 change: 1 addition & 0 deletions sagemaker-core/src/sagemaker/core/analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
"""Placeholder docstring"""

from __future__ import print_function, absolute_import

from abc import ABCMeta, abstractmethod
Expand Down
5 changes: 2 additions & 3 deletions sagemaker-core/src/sagemaker/core/apiutils/_base_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
"""Provides utilities for custom boto type objects."""

from __future__ import absolute_import

from sagemaker.core.apiutils import _boto_functions, _utils
Expand Down Expand Up @@ -238,8 +239,6 @@ def submit(request):
return self.with_boto(api_method(**request))

if boto_method in self._PIPELINE_CAPTURABLE_METHODS:
return self.sagemaker_session._intercept_create_request(
api_kwargs, submit, boto_method
)
return self.sagemaker_session._intercept_create_request(api_kwargs, submit, boto_method)

return submit(api_kwargs)
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
"""Provides utilities for converting between python style and boto style."""

from __future__ import absolute_import

import re
Expand Down
1 change: 1 addition & 0 deletions sagemaker-core/src/sagemaker/core/apiutils/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
"""Provides utilities for instantiating dependencies to boto-python objects."""

from __future__ import absolute_import

import random
Expand Down
1 change: 1 addition & 0 deletions sagemaker-core/src/sagemaker/core/base_deserializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
.. deprecated:: 3.0.0
Use :mod:`sagemaker.core.deserializers` instead.
"""

from __future__ import absolute_import

import warnings
Expand Down
1 change: 1 addition & 0 deletions sagemaker-core/src/sagemaker/core/base_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
.. deprecated:: 3.0.0
Use :mod:`sagemaker.core.serializers` instead.
"""

from __future__ import absolute_import

import warnings
Expand Down
1 change: 1 addition & 0 deletions sagemaker-core/src/sagemaker/core/clarify/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
SageMaker Clarify
==================
"""

from __future__ import absolute_import, print_function

import copy
Expand Down
8 changes: 3 additions & 5 deletions sagemaker-core/src/sagemaker/core/common_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
"""Placeholder docstring"""

from __future__ import absolute_import

import sys
Expand Down Expand Up @@ -442,9 +443,7 @@ def download_folder(bucket_name, prefix, target, sagemaker_session):
if not prefix.endswith("/"):
try:
file_destination = os.path.join(target, os.path.basename(prefix))
s3.Object(bucket_name, prefix).download_file(
file_destination, ExtraArgs=extra_args
)
s3.Object(bucket_name, prefix).download_file(file_destination, ExtraArgs=extra_args)
return
except botocore.exceptions.ClientError as e:
err_info = e.response["Error"]
Expand All @@ -469,7 +468,6 @@ def _download_files_under_prefix(bucket_name, prefix, target, s3, extra_args=Non
extra_args (dict): Optional extra arguments passed to each download_file call.
Used to carry ExpectedBucketOwner when the bucket is the session's default.
"""
target_real = os.path.realpath(target)
bucket = s3.Bucket(bucket_name)
for obj_sum in bucket.objects.filter(Prefix=prefix):
# if obj_sum is a folder object skip it.
Expand Down Expand Up @@ -711,7 +709,7 @@ def _create_or_update_code_dir(
"""Placeholder docstring"""
code_dir = os.path.join(model_dir, "code")
resolved_code_dir = _get_resolved_path(code_dir)

# Validate that code_dir does not resolve to a sensitive system path
for sensitive_path in _SENSITIVE_SYSTEM_PATHS:
if resolved_code_dir != "/" and resolved_code_dir.startswith(sensitive_path):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
"""Compute Resource Requirements needed to deploy a model"""

from __future__ import absolute_import

from sagemaker.core.compute_resource_requirements.resource_requirements import ( # noqa: F401
Expand Down
1 change: 1 addition & 0 deletions sagemaker-core/src/sagemaker/core/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
The schema of the config file is dictated in config_schema.py in the same module.
"""

from __future__ import absolute_import, annotations

import pathlib
Expand Down
8 changes: 8 additions & 0 deletions sagemaker-core/src/sagemaker/core/config/config_manager.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# sagemaker_config.py
"""Manager for loading and resolving SageMaker configuration values."""

import pathlib
import copy
Expand All @@ -25,6 +26,8 @@


class SageMakerConfig:
"""Manages loading and resolution of SageMaker configuration."""

_APP_NAME = "sagemaker"
_CONFIG_FILE_NAME = "config.yaml"
_DEFAULT_ADMIN_CONFIG_FILE_PATH = os.path.join(site_config_dir(_APP_NAME), _CONFIG_FILE_NAME)
Expand All @@ -46,6 +49,7 @@ def load_sagemaker_config(
s3_resource=None,
repeat_log: bool = False,
) -> dict:
"""Load the SageMaker configuration from the given paths."""
default_config_path = os.getenv(
self.ENV_VARIABLE_ADMIN_CONFIG_OVERRIDE, self._DEFAULT_ADMIN_CONFIG_FILE_PATH
)
Expand Down Expand Up @@ -87,9 +91,11 @@ def load_sagemaker_config(

@staticmethod
def validate_sagemaker_config(sagemaker_config: Optional[dict] = None):
"""Validate the given SageMaker configuration against the schema."""
jsonschema.validate(sagemaker_config, SAGEMAKER_PYTHON_SDK_CONFIG_SCHEMA)

def load_local_mode_config(self) -> Optional[dict]:
"""Load the local mode configuration."""
try:
content = self._load_config_from_file(self._DEFAULT_LOCAL_MODE_CONFIG_FILE_PATH)
except ValueError:
Expand Down Expand Up @@ -578,13 +584,15 @@ def update_nested_dictionary_with_values_from_config(

@lru_cache(maxsize=None)
def load_default_configs_for_resource_name(self, resource_name: str):
"""Load the default configs for the given resource name."""
configs_data = self.load_sagemaker_config()
if not configs_data:
logger.debug("No default configurations found for resource: %s", resource_name)
return {}
return configs_data["SageMaker"]["PythonSDK"]["Resources"].get(resource_name)

def get_resolved_config_value(self, attribute, resource_defaults, global_defaults):
"""Return the resolved configuration value for the given key path."""
if resource_defaults and attribute in resource_defaults:
return resource_defaults[attribute]
if global_defaults and attribute in global_defaults:
Expand Down
17 changes: 9 additions & 8 deletions sagemaker-core/src/sagemaker/core/config/config_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
"""This module contains/maintains the schema of the Config file."""

from __future__ import absolute_import, print_function

SECURITY_GROUP_IDS = "SecurityGroupIds"
Expand Down Expand Up @@ -542,7 +543,7 @@ def _simple_path(*args: str):
"minItems": 0,
"maxItems": 50,
},
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html#sagemaker-CreateTrainingJob-request-Environment
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html#sagemaker-CreateTrainingJob-request-Environment # noqa: E501
"environmentVariables": {
TYPE: OBJECT,
ADDITIONAL_PROPERTIES: False,
Expand All @@ -555,13 +556,13 @@ def _simple_path(*args: str):
},
"maxProperties": 48,
},
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_S3DataSource.html#sagemaker-Type-S3DataSource-S3Uri
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_S3DataSource.html#sagemaker-Type-S3DataSource-S3Uri # noqa: E501
"s3Uri": {
TYPE: "string",
"pattern": "^(https|s3)://([^/]+)/?(.*)$",
"maxLength": 1024,
},
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_AlgorithmSpecification.html#sagemaker-Type-AlgorithmSpecification-ContainerEntrypoint
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_AlgorithmSpecification.html#sagemaker-Type-AlgorithmSpecification-ContainerEntrypoint # noqa: E501
"preExecutionCommand": {TYPE: "string", "pattern": r".*"},
# Regex based on https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_PipelineDefinitionS3Location.html
# except with an additional ^ and $ for the beginning and the end to closer align to
Expand All @@ -572,7 +573,7 @@ def _simple_path(*args: str):
"minLength": 3,
"maxLength": 63,
},
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_MonitoringJobDefinition.html#sagemaker-Type-MonitoringJobDefinition-Environment
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_MonitoringJobDefinition.html#sagemaker-Type-MonitoringJobDefinition-Environment # noqa: E501
"environment-Length256-Properties50": {
TYPE: OBJECT,
ADDITIONAL_PROPERTIES: False,
Expand All @@ -585,7 +586,7 @@ def _simple_path(*args: str):
},
"maxProperties": 50,
},
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTransformJob.html#sagemaker-CreateTransformJob-request-Environment
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTransformJob.html#sagemaker-CreateTransformJob-request-Environment # noqa: E501
"environment-Length10240-Properties16": {
TYPE: OBJECT,
ADDITIONAL_PROPERTIES: False,
Expand All @@ -598,7 +599,7 @@ def _simple_path(*args: str):
},
"maxProperties": 16,
},
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_ContainerDefinition.html#sagemaker-Type-ContainerDefinition-Environment
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_ContainerDefinition.html#sagemaker-Type-ContainerDefinition-Environment # noqa: E501
"environment-Length1024-Properties16": {
TYPE: OBJECT,
ADDITIONAL_PROPERTIES: False,
Expand All @@ -611,7 +612,7 @@ def _simple_path(*args: str):
},
"maxProperties": 16,
},
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateProcessingJob.html#sagemaker-CreateProcessingJob-request-Environment
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateProcessingJob.html#sagemaker-CreateProcessingJob-request-Environment # noqa: E501
"environment-Length256-Properties100": {
TYPE: OBJECT,
ADDITIONAL_PROPERTIES: False,
Expand All @@ -624,7 +625,7 @@ def _simple_path(*args: str):
},
"maxProperties": 100,
},
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html#sagemaker-CreateTrainingJob-request-Environment
# Regex is taken from https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html#sagemaker-CreateTrainingJob-request-Environment # noqa: E501
"environment-Length512-Properties48": {
TYPE: OBJECT,
ADDITIONAL_PROPERTIES: False,
Expand Down
1 change: 1 addition & 0 deletions sagemaker-core/src/sagemaker/core/config/config_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
These utils may be used inside or outside the config module.
"""

from __future__ import absolute_import
from collections import deque

Expand Down
2 changes: 2 additions & 0 deletions sagemaker-core/src/sagemaker/core/config_schema.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""JSON schema definition for the SageMaker Python SDK configuration file."""

SAGEMAKER_PYTHON_SDK_CONFIG_SCHEMA = {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
Expand Down
Loading
Loading