Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
56eef2d
Feature store v3 (#5490)
Aditi2424 Feb 4, 2026
d5fd783
feat: feature_processor v3
bhhalim Feb 19, 2026
e91d8d2
integ tests
bhhalim Feb 20, 2026
4079a5d
fix
bhhalim Feb 25, 2026
e6721ce
chore(docs): Add API docs
bhhalim Feb 25, 2026
611f577
fix: Fix flaky integ tests
bhhalim Feb 26, 2026
6f4f490
fix diff
bhhalim Feb 27, 2026
09abb01
chore: rename parameter + cleanup comments
bhhalim Feb 27, 2026
a841d7d
Merge branch 'master' into feature-processor-v3
mollyheamazon Feb 27, 2026
aa654e4
Feature store v3 (#5490)
Aditi2424 Feb 4, 2026
7cdd077
add pyspark to test deps
bhhalim Feb 27, 2026
101824f
add test deps
bhhalim Feb 28, 2026
1e2b5fe
fix unit test deps
bhhalim Mar 2, 2026
bbf1a3f
pin setuptools<82 for feature-processor and unit tests
bhhalim Mar 2, 2026
5ca86dc
Set JAVA_HOME for integ tests which requires java
bhhalim Mar 2, 2026
beb078d
fix spark session bug
bhhalim Mar 2, 2026
7a659af
fix(feature-processor): Fix Spark session config and Ivy cache race c…
bhhalim Mar 2, 2026
59b68e8
revert previous change + create different ivy cache per test to fix c…
bhhalim Mar 3, 2026
fa59f5e
Merge branch 'master' into feature-processor-v3
BassemHalim Mar 3, 2026
a1b1bc3
revert changes to sagemaker-core
bhhalim Mar 3, 2026
3cd4686
refactor(feature-processor): Migrate to FeatureGroup resource API
bhhalim Mar 3, 2026
39f1be2
add `build` to test_requirements
bhhalim Mar 3, 2026
4797633
add upper bounds for test dependencies
bhhalim Mar 3, 2026
e2e179f
move feature-processor config to sagemaker-mlops optional deps
bhhalim Mar 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/api/sagemaker_mlops.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,12 @@ Local Development
:members:
:undoc-members:
:show-inheritance:


Feature Store
-------------

.. automodule:: sagemaker.mlops.feature_store
:members:
:undoc-members:
:show-inheritance:
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ dependencies = [
train = ["sagemaker-train"]
serve = ["sagemaker-serve"]
mlops = ["sagemaker-mlops"]
feature-processor = ["sagemaker-mlops", "pyspark==3.3.2", "sagemaker-feature-store-pyspark-3.3", "setuptools<82"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feature-processor used to require an extra pip install pip install sagemaker[feature-processor] this is because it requires extra dependencies that don't make sense to require all sagemaker users to install docs

V2 requirements: https://github.com/aws/sagemaker-python-sdk/blob/master-v2/requirements/extras/feature-processor_requirements.txt
The extra setuptools<82 is because setuptools removed a module named pkg_resources https://setuptools.pypa.io/en/latest/history.html#v82-0-0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feature-processor is a functionality within sagemaker-mlops .

From our tenet , we are creating namespaces for higher level flows such as training , inference , mlops.

Can this be within sagemaker-mlops

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it can but do we want everyone doing pip install sagemaker-mlops to install pyspark?

Also if we move it to sagemaker-mlops we would need to update all docs that reference installing sagemaker[feature-processor]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that is fine if they install pyspark .
We are providing the package/abstraction at the mlops level.

Also docs have to be updated anyways since this is a major version change with changes to imports/installations and inputs

all = ["sagemaker-train", "sagemaker-serve", "sagemaker-mlops"]

[project.urls]
Expand Down
220 changes: 220 additions & 0 deletions sagemaker-core/src/sagemaker/core/helper/session_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@
TAGS,
SESSION_DEFAULT_S3_BUCKET_PATH,
SESSION_DEFAULT_S3_OBJECT_KEY_PREFIX_PATH,
FEATURE_GROUP,
FEATURE_GROUP_ROLE_ARN_PATH,
FEATURE_GROUP_ONLINE_STORE_CONFIG_PATH,
FEATURE_GROUP_OFFLINE_STORE_CONFIG_PATH,
)

# Setting LOGGER for backward compatibility, in case users import it...
Expand Down Expand Up @@ -1607,6 +1611,222 @@ def delete_endpoint_config(self, endpoint_config_name):
logger.info("Deleting endpoint configuration with name: %s", endpoint_config_name)
self.sagemaker_client.delete_endpoint_config(EndpointConfigName=endpoint_config_name)

def delete_feature_group(self, feature_group_name):
"""Delete an Amazon SageMaker Feature Group.

Args:
feature_group_name (str): Name of the Amazon SageMaker Feature Group to delete.
"""
logger.info("Deleting feature group with name: %s", feature_group_name)
self.sagemaker_client.delete_feature_group(FeatureGroupName=feature_group_name)

def create_feature_group(
self,
feature_group_name,
record_identifier_name,
event_time_feature_name,
feature_definitions,
role_arn=None,
online_store_config=None,
offline_store_config=None,
throughput_config=None,
description=None,
tags=None,
):
Comment thread
BassemHalim marked this conversation as resolved.
Outdated
"""Create an Amazon SageMaker Feature Group.

Args:
feature_group_name (str): Name of the Feature Group.
record_identifier_name (str): Name of the record identifier feature.
event_time_feature_name (str): Name of the event time feature.
feature_definitions (list): List of feature definitions.
role_arn (str): ARN of the role used to execute the API (default: None).
Resolved from SageMaker Config if not provided.
online_store_config (dict): Online store configuration (default: None).
offline_store_config (dict): Offline store configuration (default: None).
throughput_config (dict): Throughput configuration (default: None).
description (str): Description of the Feature Group (default: None).
tags (Optional[Tags]): Tags for labeling the Feature Group (default: None).

Returns:
dict: Response from the CreateFeatureGroup API.
"""
tags = format_tags(tags)
tags = _append_project_tags(tags)
tags = self._append_sagemaker_config_tags(
tags, "{}.{}.{}".format(SAGEMAKER, FEATURE_GROUP, TAGS)
)

role_arn = resolve_value_from_config(
role_arn, FEATURE_GROUP_ROLE_ARN_PATH, sagemaker_session=self
)

inferred_online_store_config = update_nested_dictionary_with_values_from_config(
online_store_config,
FEATURE_GROUP_ONLINE_STORE_CONFIG_PATH,
sagemaker_session=self,
)
if inferred_online_store_config is not None:
# OnlineStore should be handled differently because if you set KmsKeyId, then you
# need to set EnableOnlineStore key as well
inferred_online_store_config["EnableOnlineStore"] = True

inferred_offline_store_config = update_nested_dictionary_with_values_from_config(
offline_store_config,
FEATURE_GROUP_OFFLINE_STORE_CONFIG_PATH,
sagemaker_session=self,
)

kwargs = dict(
FeatureGroupName=feature_group_name,
RecordIdentifierFeatureName=record_identifier_name,
EventTimeFeatureName=event_time_feature_name,
FeatureDefinitions=feature_definitions,
RoleArn=role_arn,
)
update_args(
kwargs,
OnlineStoreConfig=inferred_online_store_config,
OfflineStoreConfig=inferred_offline_store_config,
ThroughputConfig=throughput_config,
Description=description,
Tags=tags,
)

logger.info("Creating feature group with name: %s", feature_group_name)
return self.sagemaker_client.create_feature_group(**kwargs)

def describe_feature_group(self, feature_group_name, next_token=None):
"""Describe an Amazon SageMaker Feature Group.

Args:
feature_group_name (str): Name of the Amazon SageMaker Feature Group to describe.
next_token (str): A token for paginated results (default: None).

Returns:
dict: Response from the DescribeFeatureGroup API.
"""
args = {"FeatureGroupName": feature_group_name}
update_args(args, NextToken=next_token)
return self.sagemaker_client.describe_feature_group(**args)

def update_feature_group(
self,
feature_group_name,
feature_additions=None,
online_store_config=None,
throughput_config=None,
):
"""Update an Amazon SageMaker Feature Group.

Args:
feature_group_name (str): Name of the Amazon SageMaker Feature Group to update.
feature_additions (list): List of feature definitions to add (default: None).
online_store_config (dict): Online store configuration updates (default: None).
throughput_config (dict): Throughput configuration updates (default: None).

Returns:
dict: Response from the UpdateFeatureGroup API.
"""
args = {"FeatureGroupName": feature_group_name}
update_args(
args,
FeatureAdditions=feature_additions,
OnlineStoreConfig=online_store_config,
ThroughputConfig=throughput_config,
)
return self.sagemaker_client.update_feature_group(**args)

def list_feature_groups(
self,
name_contains=None,
feature_group_status_equals=None,
offline_store_status_equals=None,
creation_time_after=None,
creation_time_before=None,
sort_order=None,
sort_by=None,
max_results=None,
next_token=None,
):
"""List Amazon SageMaker Feature Groups.

Args:
name_contains (str): Filter by name substring (default: None).
feature_group_status_equals (str): Filter by status (default: None).
offline_store_status_equals (str): Filter by offline store status (default: None).
creation_time_after (datetime): Filter by creation time lower bound (default: None).
creation_time_before (datetime): Filter by creation time upper bound (default: None).
sort_order (str): Sort order, 'Ascending' or 'Descending' (default: None).
sort_by (str): Sort by field (default: None).
max_results (int): Maximum number of results (default: None).
next_token (str): Pagination token (default: None).

Returns:
dict: Response from the ListFeatureGroups API.
"""
args = {}
update_args(
args,
NameContains=name_contains,
FeatureGroupStatusEquals=feature_group_status_equals,
OfflineStoreStatusEquals=offline_store_status_equals,
CreationTimeAfter=creation_time_after,
CreationTimeBefore=creation_time_before,
SortOrder=sort_order,
SortBy=sort_by,
MaxResults=max_results,
NextToken=next_token,
)
return self.sagemaker_client.list_feature_groups(**args)

def update_feature_metadata(
self,
feature_group_name,
feature_name,
description=None,
parameter_additions=None,
parameter_removals=None,
):
"""Update metadata for a feature in an Amazon SageMaker Feature Group.

Args:
feature_group_name (str): Name of the Feature Group.
feature_name (str): Name of the feature to update metadata for.
description (str): Updated description for the feature (default: None).
parameter_additions (list): Parameters to add (default: None).
parameter_removals (list): Parameters to remove (default: None).

Returns:
dict: Response from the UpdateFeatureMetadata API.
"""
args = {
"FeatureGroupName": feature_group_name,
"FeatureName": feature_name,
}
update_args(
args,
Description=description,
ParameterAdditions=parameter_additions,
ParameterRemovals=parameter_removals,
)
return self.sagemaker_client.update_feature_metadata(**args)

def describe_feature_metadata(self, feature_group_name, feature_name):
"""Describe metadata for a feature in an Amazon SageMaker Feature Group.

Args:
feature_group_name (str): Name of the Feature Group.
feature_name (str): Name of the feature to describe metadata for.

Returns:
dict: Response from the DescribeFeatureMetadata API.
"""
return self.sagemaker_client.describe_feature_metadata(
FeatureGroupName=feature_group_name,
FeatureName=feature_name,
)

def wait_for_optimization_job(self, job, poll=5):
"""Wait for an Amazon SageMaker Optimization job to complete.

Expand Down
Loading
Loading