From 8bbf8524ee86d2dfedce0cfc7994eb92853e44fd Mon Sep 17 00:00:00 2001 From: Rob Howley Date: Fri, 3 Jan 2025 16:42:16 -0500 Subject: [PATCH 1/4] put blocking opps in get online features in threadpool Signed-off-by: Rob Howley --- sdk/python/feast/feature_server.py | 74 +++++++++++++++++------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/sdk/python/feast/feature_server.py b/sdk/python/feast/feature_server.py index 26ee604e79f..543671b02dd 100644 --- a/sdk/python/feast/feature_server.py +++ b/sdk/python/feast/feature_server.py @@ -17,7 +17,7 @@ from pydantic import BaseModel import feast -from feast import proto_json, utils +from feast import proto_json, utils, FeatureService from feast.constants import DEFAULT_FEATURE_SERVER_REGISTRY_TTL from feast.data_source import PushMode from feast.errors import ( @@ -75,6 +75,41 @@ class GetOnlineFeaturesRequest(BaseModel): full_feature_names: bool = False +def _get_features( + request: GetOnlineFeaturesRequest, store: "feast.FeatureStore" +) -> list[str] | FeatureService: + # Initialize parameters for FeatureStore.get_online_features(...) call + if request.feature_service: + feature_service = store.get_feature_service( + request.feature_service, allow_cache=True + ) + assert_permissions( + resource=feature_service, actions=[AuthzedAction.READ_ONLINE] + ) + features = feature_service # type: ignore + else: + all_feature_views, all_on_demand_feature_views = ( + utils._get_feature_views_to_use( + store.registry, + store.project, + request.features, + allow_cache=True, + hide_dummy_entity=False, + ) + ) + for feature_view in all_feature_views: + assert_permissions( + resource=feature_view, actions=[AuthzedAction.READ_ONLINE] + ) + for od_feature_view in all_on_demand_feature_views: + assert_permissions( + resource=od_feature_view, actions=[AuthzedAction.READ_ONLINE] + ) + features = request.features # type: ignore + + return features + + def get_app( store: "feast.FeatureStore", registry_ttl_sec: int = DEFAULT_FEATURE_SERVER_REGISTRY_TTL, @@ -119,34 +154,7 @@ async def lifespan(app: FastAPI): dependencies=[Depends(inject_user_details)], ) async def get_online_features(request: GetOnlineFeaturesRequest) -> Dict[str, Any]: - # Initialize parameters for FeatureStore.get_online_features(...) call - if request.feature_service: - feature_service = store.get_feature_service( - request.feature_service, allow_cache=True - ) - assert_permissions( - resource=feature_service, actions=[AuthzedAction.READ_ONLINE] - ) - features = feature_service # type: ignore - else: - all_feature_views, all_on_demand_feature_views = ( - utils._get_feature_views_to_use( - store.registry, - store.project, - request.features, - allow_cache=True, - hide_dummy_entity=False, - ) - ) - for feature_view in all_feature_views: - assert_permissions( - resource=feature_view, actions=[AuthzedAction.READ_ONLINE] - ) - for od_feature_view in all_on_demand_feature_views: - assert_permissions( - resource=od_feature_view, actions=[AuthzedAction.READ_ONLINE] - ) - features = request.features # type: ignore + features = await run_in_threadpool(_get_features, request, store) read_params = dict( features=features, @@ -162,9 +170,13 @@ async def get_online_features(request: GetOnlineFeaturesRequest) -> Dict[str, An ) # Convert the Protobuf object to JSON and return it - return MessageToDict( - response.proto, preserving_proto_field_name=True, float_precision=18 + response_dict = await run_in_threadpool( + MessageToDict, + response.proto, + preserving_proto_field_name=True, + float_precision=18, ) + return response_dict @app.post("/push", dependencies=[Depends(inject_user_details)]) async def push(request: PushFeaturesRequest) -> None: From 9d87ff0de3f1a58caadfb48e4e8661fae2793971 Mon Sep 17 00:00:00 2001 From: Rob Howley Date: Fri, 3 Jan 2025 16:44:17 -0500 Subject: [PATCH 2/4] chore: leave comment in path operation Signed-off-by: Rob Howley --- sdk/python/feast/feature_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/feast/feature_server.py b/sdk/python/feast/feature_server.py index 543671b02dd..b7cf50a45a2 100644 --- a/sdk/python/feast/feature_server.py +++ b/sdk/python/feast/feature_server.py @@ -78,7 +78,6 @@ class GetOnlineFeaturesRequest(BaseModel): def _get_features( request: GetOnlineFeaturesRequest, store: "feast.FeatureStore" ) -> list[str] | FeatureService: - # Initialize parameters for FeatureStore.get_online_features(...) call if request.feature_service: feature_service = store.get_feature_service( request.feature_service, allow_cache=True @@ -154,6 +153,7 @@ async def lifespan(app: FastAPI): dependencies=[Depends(inject_user_details)], ) async def get_online_features(request: GetOnlineFeaturesRequest) -> Dict[str, Any]: + # Initialize parameters for FeatureStore.get_online_features(...) call features = await run_in_threadpool(_get_features, request, store) read_params = dict( From 13fc65a48d40ef4895f1e434d73cf3ec2d8ad3aa Mon Sep 17 00:00:00 2001 From: Rob Howley Date: Fri, 3 Jan 2025 16:48:52 -0500 Subject: [PATCH 3/4] use quoted type hint Signed-off-by: Rob Howley --- sdk/python/feast/feature_server.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/python/feast/feature_server.py b/sdk/python/feast/feature_server.py index b7cf50a45a2..7052c3237ff 100644 --- a/sdk/python/feast/feature_server.py +++ b/sdk/python/feast/feature_server.py @@ -17,7 +17,7 @@ from pydantic import BaseModel import feast -from feast import proto_json, utils, FeatureService +from feast import proto_json, utils from feast.constants import DEFAULT_FEATURE_SERVER_REGISTRY_TTL from feast.data_source import PushMode from feast.errors import ( @@ -77,7 +77,7 @@ class GetOnlineFeaturesRequest(BaseModel): def _get_features( request: GetOnlineFeaturesRequest, store: "feast.FeatureStore" -) -> list[str] | FeatureService: +) -> list[str] | "feast.FeatureService": if request.feature_service: feature_service = store.get_feature_service( request.feature_service, allow_cache=True From 254ae7ef98b90c05577185d11e02757107b97978 Mon Sep 17 00:00:00 2001 From: Rob Howley Date: Fri, 3 Jan 2025 16:51:33 -0500 Subject: [PATCH 4/4] remove hint Signed-off-by: Rob Howley --- sdk/python/feast/feature_server.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sdk/python/feast/feature_server.py b/sdk/python/feast/feature_server.py index 7052c3237ff..7f519c138c8 100644 --- a/sdk/python/feast/feature_server.py +++ b/sdk/python/feast/feature_server.py @@ -75,9 +75,7 @@ class GetOnlineFeaturesRequest(BaseModel): full_feature_names: bool = False -def _get_features( - request: GetOnlineFeaturesRequest, store: "feast.FeatureStore" -) -> list[str] | "feast.FeatureService": +def _get_features(request: GetOnlineFeaturesRequest, store: "feast.FeatureStore"): if request.feature_service: feature_service = store.get_feature_service( request.feature_service, allow_cache=True