From 7ad24e1257219f5175c7568fe166ecde0f8453a0 Mon Sep 17 00:00:00 2001 From: ntkathole Date: Sun, 6 Jul 2025 20:42:46 +0530 Subject: [PATCH] feat: Support pagination and sorting on registry apis Signed-off-by: ntkathole --- protos/feast/registry/RegistryServer.proto | 60 ++ .../feast/api/registry/rest/data_sources.py | 19 +- .../feast/api/registry/rest/entities.py | 26 +- .../api/registry/rest/feature_services.py | 13 +- .../feast/api/registry/rest/feature_views.py | 24 +- sdk/python/feast/api/registry/rest/lineage.py | 83 ++- .../feast/api/registry/rest/permissions.py | 16 +- .../feast/api/registry/rest/projects.py | 18 +- .../feast/api/registry/rest/rest_utils.py | 41 +- .../feast/api/registry/rest/saved_datasets.py | 25 +- .../feast/registry/RegistryServer_pb2.py | 308 +++++----- .../feast/registry/RegistryServer_pb2.pyi | 309 +++++++++- sdk/python/feast/registry_server.py | 537 ++++++++++++------ .../tests/unit/api/test_api_rest_registry.py | 491 ++++++++++++++++ 14 files changed, 1584 insertions(+), 386 deletions(-) diff --git a/protos/feast/registry/RegistryServer.proto b/protos/feast/registry/RegistryServer.proto index 108e0a8aa52..b16bebbb198 100644 --- a/protos/feast/registry/RegistryServer.proto +++ b/protos/feast/registry/RegistryServer.proto @@ -94,6 +94,26 @@ service RegistryServer{ } +// Common pagination and sorting messages +message PaginationParams { + int32 page = 1; // 1-based page number + int32 limit = 2; // Number of items per page +} + +message SortingParams { + string sort_by = 1; // Field to sort by (supports dot notation) + string sort_order = 2; // "asc" or "desc" +} + +message PaginationMetadata { + int32 page = 1; + int32 limit = 2; + int32 total_count = 3; + int32 total_pages = 4; + bool has_next = 5; + bool has_previous = 6; +} + message RefreshRequest { string project = 1; } @@ -142,10 +162,13 @@ message ListEntitiesRequest { string project = 1; bool allow_cache = 2; map tags = 3; + PaginationParams pagination = 4; + SortingParams sorting = 5; } message ListEntitiesResponse { repeated feast.core.Entity entities = 1; + PaginationMetadata pagination = 2; } message DeleteEntityRequest { @@ -172,10 +195,13 @@ message ListDataSourcesRequest { string project = 1; bool allow_cache = 2; map tags = 3; + PaginationParams pagination = 4; + SortingParams sorting = 5; } message ListDataSourcesResponse { repeated feast.core.DataSource data_sources = 1; + PaginationMetadata pagination = 2; } message DeleteDataSourceRequest { @@ -206,10 +232,13 @@ message ListFeatureViewsRequest { string project = 1; bool allow_cache = 2; map tags = 3; + PaginationParams pagination = 4; + SortingParams sorting = 5; } message ListFeatureViewsResponse { repeated feast.core.FeatureView feature_views = 1; + PaginationMetadata pagination = 2; } message DeleteFeatureViewRequest { @@ -240,10 +269,13 @@ message ListAllFeatureViewsRequest { string project = 1; bool allow_cache = 2; map tags = 3; + PaginationParams pagination = 4; + SortingParams sorting = 5; } message ListAllFeatureViewsResponse { repeated AnyFeatureView feature_views = 1; + PaginationMetadata pagination = 2; } @@ -259,10 +291,13 @@ message ListStreamFeatureViewsRequest { string project = 1; bool allow_cache = 2; map tags = 3; + PaginationParams pagination = 4; + SortingParams sorting = 5; } message ListStreamFeatureViewsResponse { repeated feast.core.StreamFeatureView stream_feature_views = 1; + PaginationMetadata pagination = 2; } // OnDemandFeatureView @@ -277,10 +312,13 @@ message ListOnDemandFeatureViewsRequest { string project = 1; bool allow_cache = 2; map tags = 3; + PaginationParams pagination = 4; + SortingParams sorting = 5; } message ListOnDemandFeatureViewsResponse { repeated feast.core.OnDemandFeatureView on_demand_feature_views = 1; + PaginationMetadata pagination = 2; } // FeatureServices @@ -301,10 +339,13 @@ message ListFeatureServicesRequest { string project = 1; bool allow_cache = 2; map tags = 3; + PaginationParams pagination = 4; + SortingParams sorting = 5; } message ListFeatureServicesResponse { repeated feast.core.FeatureService feature_services = 1; + PaginationMetadata pagination = 2; } message DeleteFeatureServiceRequest { @@ -331,10 +372,13 @@ message ListSavedDatasetsRequest { string project = 1; bool allow_cache = 2; map tags = 3; + PaginationParams pagination = 4; + SortingParams sorting = 5; } message ListSavedDatasetsResponse { repeated feast.core.SavedDataset saved_datasets = 1; + PaginationMetadata pagination = 2; } message DeleteSavedDatasetRequest { @@ -361,10 +405,13 @@ message ListValidationReferencesRequest { string project = 1; bool allow_cache = 2; map tags = 3; + PaginationParams pagination = 4; + SortingParams sorting = 5; } message ListValidationReferencesResponse { repeated feast.core.ValidationReference validation_references = 1; + PaginationMetadata pagination = 2; } message DeleteValidationReferenceRequest { @@ -391,10 +438,13 @@ message ListPermissionsRequest { string project = 1; bool allow_cache = 2; map tags = 3; + PaginationParams pagination = 4; + SortingParams sorting = 5; } message ListPermissionsResponse { repeated feast.core.Permission permissions = 1; + PaginationMetadata pagination = 2; } message DeletePermissionRequest { @@ -418,10 +468,13 @@ message GetProjectRequest { message ListProjectsRequest { bool allow_cache = 1; map tags = 2; + PaginationParams pagination = 3; + SortingParams sorting = 4; } message ListProjectsResponse { repeated feast.core.Project projects = 1; + PaginationMetadata pagination = 2; } message DeleteProjectRequest { @@ -446,11 +499,15 @@ message GetRegistryLineageRequest { bool allow_cache = 2; string filter_object_type = 3; string filter_object_name = 4; + PaginationParams pagination = 5; + SortingParams sorting = 6; } message GetRegistryLineageResponse { repeated EntityRelation relationships = 1; repeated EntityRelation indirect_relationships = 2; + PaginationMetadata relationships_pagination = 3; + PaginationMetadata indirect_relationships_pagination = 4; } message GetObjectRelationshipsRequest { @@ -459,8 +516,11 @@ message GetObjectRelationshipsRequest { string object_name = 3; bool include_indirect = 4; bool allow_cache = 5; + PaginationParams pagination = 6; + SortingParams sorting = 7; } message GetObjectRelationshipsResponse { repeated EntityRelation relationships = 1; + PaginationMetadata pagination = 2; } diff --git a/sdk/python/feast/api/registry/rest/data_sources.py b/sdk/python/feast/api/registry/rest/data_sources.py index 05d7c51e30f..248872fabec 100644 --- a/sdk/python/feast/api/registry/rest/data_sources.py +++ b/sdk/python/feast/api/registry/rest/data_sources.py @@ -3,7 +3,14 @@ from fastapi import APIRouter, Depends, Query -from feast.api.registry.rest.rest_utils import grpc_call, parse_tags +from feast.api.registry.rest.rest_utils import ( + create_grpc_pagination_params, + create_grpc_sorting_params, + get_pagination_params, + get_sorting_params, + grpc_call, + parse_tags, +) from feast.protos.feast.registry import RegistryServer_pb2 logger = logging.getLogger(__name__) @@ -17,14 +24,22 @@ def list_data_sources( project: str = Query(...), allow_cache: bool = Query(default=True), tags: Dict[str, str] = Depends(parse_tags), + pagination_params: dict = Depends(get_pagination_params), + sorting_params: dict = Depends(get_sorting_params), ): req = RegistryServer_pb2.ListDataSourcesRequest( project=project, allow_cache=allow_cache, tags=tags, + pagination=create_grpc_pagination_params(pagination_params), + sorting=create_grpc_sorting_params(sorting_params), ) + response = grpc_call(grpc_handler.ListDataSources, req) - return {"data_sources": response.get("dataSources", [])} + return { + "data_sources": response.get("dataSources", []), + "pagination": response.get("pagination", {}), + } @router.get("/data_sources/{name}") def get_data_source( diff --git a/sdk/python/feast/api/registry/rest/entities.py b/sdk/python/feast/api/registry/rest/entities.py index fdbd3110bf8..ed9d196d889 100644 --- a/sdk/python/feast/api/registry/rest/entities.py +++ b/sdk/python/feast/api/registry/rest/entities.py @@ -1,8 +1,14 @@ import logging -from fastapi import APIRouter, Query - -from feast.api.registry.rest.rest_utils import grpc_call +from fastapi import APIRouter, Depends, Query + +from feast.api.registry.rest.rest_utils import ( + create_grpc_pagination_params, + create_grpc_sorting_params, + get_pagination_params, + get_sorting_params, + grpc_call, +) from feast.protos.feast.registry import RegistryServer_pb2 logger = logging.getLogger(__name__) @@ -14,10 +20,18 @@ def get_entity_router(grpc_handler) -> APIRouter: @router.get("/entities") def list_entities( project: str = Query(...), + allow_cache: bool = Query(default=True), + pagination_params: dict = Depends(get_pagination_params), + sorting_params: dict = Depends(get_sorting_params), ): - req = RegistryServer_pb2.ListEntitiesRequest(project=project) - response = grpc_call(grpc_handler.ListEntities, req) - return {"entities": response.get("entities", [])} + req = RegistryServer_pb2.ListEntitiesRequest( + project=project, + allow_cache=allow_cache, + pagination=create_grpc_pagination_params(pagination_params), + sorting=create_grpc_sorting_params(sorting_params), + ) + + return grpc_call(grpc_handler.ListEntities, req) @router.get("/entities/{name}") def get_entity( diff --git a/sdk/python/feast/api/registry/rest/feature_services.py b/sdk/python/feast/api/registry/rest/feature_services.py index b8fb7c70de6..ac9b45a071f 100644 --- a/sdk/python/feast/api/registry/rest/feature_services.py +++ b/sdk/python/feast/api/registry/rest/feature_services.py @@ -2,7 +2,14 @@ from fastapi import APIRouter, Depends, Query -from feast.api.registry.rest.rest_utils import grpc_call, parse_tags +from feast.api.registry.rest.rest_utils import ( + create_grpc_pagination_params, + create_grpc_sorting_params, + get_pagination_params, + get_sorting_params, + grpc_call, + parse_tags, +) from feast.protos.feast.registry import RegistryServer_pb2 @@ -14,11 +21,15 @@ def list_feature_services( project: str = Query(...), allow_cache: bool = Query(default=True), tags: Dict[str, str] = Depends(parse_tags), + pagination_params: dict = Depends(get_pagination_params), + sorting_params: dict = Depends(get_sorting_params), ): req = RegistryServer_pb2.ListFeatureServicesRequest( project=project, allow_cache=allow_cache, tags=tags, + pagination=create_grpc_pagination_params(pagination_params), + sorting=create_grpc_sorting_params(sorting_params), ) return grpc_call(grpc_handler.ListFeatureServices, req) diff --git a/sdk/python/feast/api/registry/rest/feature_views.py b/sdk/python/feast/api/registry/rest/feature_views.py index 809dcae8366..ce5f8ac0f1e 100644 --- a/sdk/python/feast/api/registry/rest/feature_views.py +++ b/sdk/python/feast/api/registry/rest/feature_views.py @@ -2,7 +2,14 @@ from fastapi import APIRouter, Depends, Query -from feast.api.registry.rest.rest_utils import grpc_call, parse_tags +from feast.api.registry.rest.rest_utils import ( + create_grpc_pagination_params, + create_grpc_sorting_params, + get_pagination_params, + get_sorting_params, + grpc_call, + parse_tags, +) from feast.registry_server import RegistryServer_pb2 @@ -21,18 +28,29 @@ def get_any_feature_view( allow_cache=allow_cache, ) response = grpc_call(grpc_handler.GetAnyFeatureView, req) - return response.get("anyFeatureView", {}) + any_feature_view = response.get("anyFeatureView", {}) + feature_view = ( + any_feature_view.get("featureView") + or any_feature_view.get("onDemandFeatureView") + or any_feature_view.get("streamFeatureView") + or {} + ) + return {"featureView": feature_view} @router.get("/feature_views") def list_all_feature_views( project: str = Query(...), - allow_cache: bool = Query(True), + allow_cache: bool = Query(default=True), tags: Dict[str, str] = Depends(parse_tags), + pagination_params: dict = Depends(get_pagination_params), + sorting_params: dict = Depends(get_sorting_params), ): req = RegistryServer_pb2.ListAllFeatureViewsRequest( project=project, allow_cache=allow_cache, tags=tags, + pagination=create_grpc_pagination_params(pagination_params), + sorting=create_grpc_sorting_params(sorting_params), ) return grpc_call(grpc_handler.ListAllFeatureViews, req) diff --git a/sdk/python/feast/api/registry/rest/lineage.py b/sdk/python/feast/api/registry/rest/lineage.py index 333bac0090d..d4b66fce05b 100644 --- a/sdk/python/feast/api/registry/rest/lineage.py +++ b/sdk/python/feast/api/registry/rest/lineage.py @@ -2,9 +2,15 @@ from typing import Optional -from fastapi import APIRouter, HTTPException, Query - -from feast.api.registry.rest.rest_utils import grpc_call +from fastapi import APIRouter, Depends, HTTPException, Query + +from feast.api.registry.rest.rest_utils import ( + create_grpc_pagination_params, + create_grpc_sorting_params, + get_pagination_params, + get_sorting_params, + grpc_call, +) from feast.protos.feast.registry import RegistryServer_pb2 @@ -17,6 +23,8 @@ def get_registry_lineage( allow_cache: bool = Query(True), filter_object_type: Optional[str] = Query(None), filter_object_name: Optional[str] = Query(None), + pagination_params: dict = Depends(get_pagination_params), + sorting_params: dict = Depends(get_sorting_params), ): """ Get complete registry lineage with relationships and indirect relationships. @@ -33,21 +41,29 @@ def get_registry_lineage( allow_cache=allow_cache, filter_object_type=filter_object_type or "", filter_object_name=filter_object_name or "", + pagination=create_grpc_pagination_params(pagination_params), + sorting=create_grpc_sorting_params(sorting_params), ) - response = grpc_call(grpc_handler.GetRegistryLineage, req) + response = grpc_call(grpc_handler.GetRegistryLineage, req) return { "relationships": response.get("relationships", []), "indirect_relationships": response.get("indirectRelationships", []), + "relationships_pagination": response.get("relationshipsPagination", {}), + "indirect_relationships_pagination": response.get( + "indirectRelationshipsPagination", {} + ), } @router.get("/lineage/objects/{object_type}/{object_name}") - def get_object_relationships( + def get_object_relationships_path( object_type: str, object_name: str, project: str = Query(...), include_indirect: bool = Query(False), allow_cache: bool = Query(True), + pagination_params: dict = Depends(get_pagination_params), + sorting_params: dict = Depends(get_sorting_params), ): """ Get relationships for a specific object. @@ -64,7 +80,7 @@ def get_object_relationships( if object_type not in valid_types: raise HTTPException( status_code=400, - detail=f"Invalid object_type. Must be one of: {valid_types}", + detail=f"Invalid object_type. Must be one of: {', '.join(valid_types)}", ) req = RegistryServer_pb2.GetObjectRelationshipsRequest( @@ -73,15 +89,18 @@ def get_object_relationships( object_name=object_name, include_indirect=include_indirect, allow_cache=allow_cache, + pagination=create_grpc_pagination_params(pagination_params), + sorting=create_grpc_sorting_params(sorting_params), ) - response = grpc_call(grpc_handler.GetObjectRelationships, req) - return {"relationships": response.get("relationships", [])} + return grpc_call(grpc_handler.GetObjectRelationships, req) @router.get("/lineage/complete") def get_complete_registry_data( project: str = Query(...), allow_cache: bool = Query(True), + pagination_params: dict = Depends(get_pagination_params), + sorting_params: dict = Depends(get_sorting_params), ): """ Get complete registry data. @@ -90,38 +109,66 @@ def get_complete_registry_data( - Relationships - Indirect relationships - Merged feature view data + + Args: + project: Project name + allow_cache: Whether to allow cached data + pagination_params: Pagination parameters (page, page_size) + sorting_params: Sorting parameters (sort_by, sort_order) + Returns: - Complete registry data structure. + Complete registry data structure with pagination metadata. + + Note: + Pagination and sorting are applied to each object type separately. """ + # Create pagination and sorting parameters for gRPC calls + grpc_pagination = create_grpc_pagination_params(pagination_params) + grpc_sorting = create_grpc_sorting_params(sorting_params) + # Get lineage data lineage_req = RegistryServer_pb2.GetRegistryLineageRequest( project=project, allow_cache=allow_cache, + pagination=grpc_pagination, + sorting=grpc_sorting, ) lineage_response = grpc_call(grpc_handler.GetRegistryLineage, lineage_req) # Get all registry objects entities_req = RegistryServer_pb2.ListEntitiesRequest( - project=project, allow_cache=allow_cache + project=project, + allow_cache=allow_cache, + pagination=grpc_pagination, + sorting=grpc_sorting, ) entities_response = grpc_call(grpc_handler.ListEntities, entities_req) data_sources_req = RegistryServer_pb2.ListDataSourcesRequest( - project=project, allow_cache=allow_cache + project=project, + allow_cache=allow_cache, + pagination=grpc_pagination, + sorting=grpc_sorting, ) data_sources_response = grpc_call( grpc_handler.ListDataSources, data_sources_req ) feature_views_req = RegistryServer_pb2.ListAllFeatureViewsRequest( - project=project, allow_cache=allow_cache + project=project, + allow_cache=allow_cache, + pagination=grpc_pagination, + sorting=grpc_sorting, ) feature_views_response = grpc_call( grpc_handler.ListAllFeatureViews, feature_views_req ) feature_services_req = RegistryServer_pb2.ListFeatureServicesRequest( - project=project, allow_cache=allow_cache + project=project, + allow_cache=allow_cache, + pagination=grpc_pagination, + sorting=grpc_sorting, ) feature_services_response = grpc_call( grpc_handler.ListFeatureServices, feature_services_req @@ -137,6 +184,16 @@ def get_complete_registry_data( }, "relationships": lineage_response.get("relationships", []), "indirectRelationships": lineage_response.get("indirectRelationships", []), + "pagination": { + "entities": entities_response.get("pagination", {}), + "dataSources": data_sources_response.get("pagination", {}), + "featureViews": feature_views_response.get("pagination", {}), + "featureServices": feature_services_response.get("pagination", {}), + "relationships": lineage_response.get("relationshipsPagination", {}), + "indirectRelationships": lineage_response.get( + "indirectRelationshipsPagination", {} + ), + }, } return router diff --git a/sdk/python/feast/api/registry/rest/permissions.py b/sdk/python/feast/api/registry/rest/permissions.py index 36e0760453f..b10f4289e68 100644 --- a/sdk/python/feast/api/registry/rest/permissions.py +++ b/sdk/python/feast/api/registry/rest/permissions.py @@ -1,6 +1,12 @@ -from fastapi import APIRouter, Query +from fastapi import APIRouter, Depends, Query -from feast.api.registry.rest.rest_utils import grpc_call +from feast.api.registry.rest.rest_utils import ( + create_grpc_pagination_params, + create_grpc_sorting_params, + get_pagination_params, + get_sorting_params, + grpc_call, +) from feast.registry_server import RegistryServer_pb2 @@ -23,11 +29,15 @@ def get_permission( @router.get("/permissions") def list_permissions( project: str = Query(...), - allow_cache: bool = Query(True), + allow_cache: bool = Query(default=True), + pagination_params: dict = Depends(get_pagination_params), + sorting_params: dict = Depends(get_sorting_params), ): req = RegistryServer_pb2.ListPermissionsRequest( project=project, allow_cache=allow_cache, + pagination=create_grpc_pagination_params(pagination_params), + sorting=create_grpc_sorting_params(sorting_params), ) return grpc_call(grpc_handler.ListPermissions, req) diff --git a/sdk/python/feast/api/registry/rest/projects.py b/sdk/python/feast/api/registry/rest/projects.py index 89bc620b001..41763b13e3e 100644 --- a/sdk/python/feast/api/registry/rest/projects.py +++ b/sdk/python/feast/api/registry/rest/projects.py @@ -1,6 +1,12 @@ -from fastapi import APIRouter, Query +from fastapi import APIRouter, Depends, Query -from feast.api.registry.rest.rest_utils import grpc_call +from feast.api.registry.rest.rest_utils import ( + create_grpc_pagination_params, + create_grpc_sorting_params, + get_pagination_params, + get_sorting_params, + grpc_call, +) from feast.protos.feast.registry import RegistryServer_pb2 @@ -21,11 +27,15 @@ def get_project( @router.get("/projects") def list_projects( allow_cache: bool = Query(True), + pagination_params: dict = Depends(get_pagination_params), + sorting_params: dict = Depends(get_sorting_params), ): req = RegistryServer_pb2.ListProjectsRequest( allow_cache=allow_cache, + pagination=create_grpc_pagination_params(pagination_params), + sorting=create_grpc_sorting_params(sorting_params), ) - response = grpc_call(grpc_handler.ListProjects, req) - return {"projects": response.get("projects", [])} + + return grpc_call(grpc_handler.ListProjects, req) return router diff --git a/sdk/python/feast/api/registry/rest/rest_utils.py b/sdk/python/feast/api/registry/rest/rest_utils.py index 62e81f09401..bddc31c9a98 100644 --- a/sdk/python/feast/api/registry/rest/rest_utils.py +++ b/sdk/python/feast/api/registry/rest/rest_utils.py @@ -1,9 +1,10 @@ -from typing import Dict, List +from typing import Dict, List, Optional from fastapi import HTTPException, Query from google.protobuf.json_format import MessageToDict from feast.errors import FeastObjectNotFoundException +from feast.protos.feast.registry import RegistryServer_pb2 def grpc_call(handler_fn, request): @@ -30,3 +31,41 @@ def parse_tags(tags: List[str] = Query(default=[])) -> Dict[str, str]: key, value = tag.split(":", 1) parsed_tags[key] = value return parsed_tags + + +def get_pagination_params( + page: Optional[int] = Query(None, ge=1), + limit: Optional[int] = Query(None, ge=1, le=100), +) -> dict: + return { + "page": page or 0, + "limit": limit or 0, + } + + +def get_sorting_params( + sort_by: Optional[str] = Query(None), + sort_order: Optional[str] = Query(None, regex="^(asc|desc)$"), +) -> dict: + return { + "sort_by": sort_by or "", + "sort_order": sort_order or "asc", + } + + +def create_grpc_pagination_params( + pagination_params: dict, +) -> RegistryServer_pb2.PaginationParams: + return RegistryServer_pb2.PaginationParams( + page=pagination_params.get("page", 0), + limit=pagination_params.get("limit", 0), + ) + + +def create_grpc_sorting_params( + sorting_params: dict, +) -> RegistryServer_pb2.SortingParams: + return RegistryServer_pb2.SortingParams( + sort_by=sorting_params.get("sort_by", ""), + sort_order=sorting_params.get("sort_order", "asc"), + ) diff --git a/sdk/python/feast/api/registry/rest/saved_datasets.py b/sdk/python/feast/api/registry/rest/saved_datasets.py index fc79edb65c3..3d0932b50cf 100644 --- a/sdk/python/feast/api/registry/rest/saved_datasets.py +++ b/sdk/python/feast/api/registry/rest/saved_datasets.py @@ -1,6 +1,15 @@ +from typing import Dict + from fastapi import APIRouter, Depends, Query -from feast.api.registry.rest.rest_utils import grpc_call, parse_tags +from feast.api.registry.rest.rest_utils import ( + create_grpc_pagination_params, + create_grpc_sorting_params, + get_pagination_params, + get_sorting_params, + grpc_call, + parse_tags, +) from feast.protos.feast.registry import RegistryServer_pb2 @@ -23,15 +32,23 @@ def get_saved_dataset( @router.get("/saved_datasets") def list_saved_datasets( project: str = Query(...), - allow_cache: bool = Query(True), - tags: dict = Depends(parse_tags), + allow_cache: bool = Query(default=True), + tags: Dict[str, str] = Depends(parse_tags), + pagination_params: dict = Depends(get_pagination_params), + sorting_params: dict = Depends(get_sorting_params), ): req = RegistryServer_pb2.ListSavedDatasetsRequest( project=project, allow_cache=allow_cache, tags=tags, + pagination=create_grpc_pagination_params(pagination_params), + sorting=create_grpc_sorting_params(sorting_params), ) + response = grpc_call(grpc_handler.ListSavedDatasets, req) - return {"saved_datasets": response.get("savedDatasets", [])} + return { + "saved_datasets": response.get("savedDatasets", []), + "pagination": response.get("pagination", {}), + } return router diff --git a/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.py b/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.py index 37af594eaed..efe2ecea418 100644 --- a/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.py +++ b/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.py @@ -28,7 +28,7 @@ from feast.protos.feast.core import Project_pb2 as feast_dot_core_dot_Project__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#feast/registry/RegistryServer.proto\x12\x0e\x66\x65\x61st.registry\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19\x66\x65\x61st/core/Registry.proto\x1a\x17\x66\x65\x61st/core/Entity.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\x1a\x1c\x66\x65\x61st/core/FeatureView.proto\x1a\"feast/core/StreamFeatureView.proto\x1a$feast/core/OnDemandFeatureView.proto\x1a\x1f\x66\x65\x61st/core/FeatureService.proto\x1a\x1d\x66\x65\x61st/core/SavedDataset.proto\x1a\"feast/core/ValidationProfile.proto\x1a\x1c\x66\x65\x61st/core/InfraObject.proto\x1a\x1b\x66\x65\x61st/core/Permission.proto\x1a\x18\x66\x65\x61st/core/Project.proto\"!\n\x0eRefreshRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\"W\n\x12UpdateInfraRequest\x12 \n\x05infra\x18\x01 \x01(\x0b\x32\x11.feast.core.Infra\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"7\n\x0fGetInfraRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\"B\n\x1aListProjectMetadataRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\"T\n\x1bListProjectMetadataResponse\x12\x35\n\x10project_metadata\x18\x01 \x03(\x0b\x32\x1b.feast.core.ProjectMetadata\"\xcb\x01\n\x1b\x41pplyMaterializationRequest\x12-\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureView\x12\x0f\n\x07project\x18\x02 \x01(\t\x12.\n\nstart_date\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_date\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0e\n\x06\x63ommit\x18\x05 \x01(\x08\"Y\n\x12\x41pplyEntityRequest\x12\"\n\x06\x65ntity\x18\x01 \x01(\x0b\x32\x12.feast.core.Entity\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"F\n\x10GetEntityRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xa5\x01\n\x13ListEntitiesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12;\n\x04tags\x18\x03 \x03(\x0b\x32-.feast.registry.ListEntitiesRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"<\n\x14ListEntitiesResponse\x12$\n\x08\x65ntities\x18\x01 \x03(\x0b\x32\x12.feast.core.Entity\"D\n\x13\x44\x65leteEntityRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"f\n\x16\x41pplyDataSourceRequest\x12+\n\x0b\x64\x61ta_source\x18\x01 \x01(\x0b\x32\x16.feast.core.DataSource\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"J\n\x14GetDataSourceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xab\x01\n\x16ListDataSourcesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12>\n\x04tags\x18\x03 \x03(\x0b\x32\x30.feast.registry.ListDataSourcesRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"G\n\x17ListDataSourcesResponse\x12,\n\x0c\x64\x61ta_sources\x18\x01 \x03(\x0b\x32\x16.feast.core.DataSource\"H\n\x17\x44\x65leteDataSourceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"\x81\x02\n\x17\x41pplyFeatureViewRequest\x12/\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureViewH\x00\x12\x41\n\x16on_demand_feature_view\x18\x02 \x01(\x0b\x32\x1f.feast.core.OnDemandFeatureViewH\x00\x12<\n\x13stream_feature_view\x18\x03 \x01(\x0b\x32\x1d.feast.core.StreamFeatureViewH\x00\x12\x0f\n\x07project\x18\x04 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x05 \x01(\x08\x42\x13\n\x11\x62\x61se_feature_view\"K\n\x15GetFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xad\x01\n\x17ListFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12?\n\x04tags\x18\x03 \x03(\x0b\x32\x31.feast.registry.ListFeatureViewsRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"J\n\x18ListFeatureViewsResponse\x12.\n\rfeature_views\x18\x01 \x03(\x0b\x32\x17.feast.core.FeatureView\"I\n\x18\x44\x65leteFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"\xd6\x01\n\x0e\x41nyFeatureView\x12/\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureViewH\x00\x12\x41\n\x16on_demand_feature_view\x18\x02 \x01(\x0b\x32\x1f.feast.core.OnDemandFeatureViewH\x00\x12<\n\x13stream_feature_view\x18\x03 \x01(\x0b\x32\x1d.feast.core.StreamFeatureViewH\x00\x42\x12\n\x10\x61ny_feature_view\"N\n\x18GetAnyFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"U\n\x19GetAnyFeatureViewResponse\x12\x38\n\x10\x61ny_feature_view\x18\x01 \x01(\x0b\x32\x1e.feast.registry.AnyFeatureView\"\xb3\x01\n\x1aListAllFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x42\n\x04tags\x18\x03 \x03(\x0b\x32\x34.feast.registry.ListAllFeatureViewsRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"T\n\x1bListAllFeatureViewsResponse\x12\x35\n\rfeature_views\x18\x01 \x03(\x0b\x32\x1e.feast.registry.AnyFeatureView\"Q\n\x1bGetStreamFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xb9\x01\n\x1dListStreamFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x45\n\x04tags\x18\x03 \x03(\x0b\x32\x37.feast.registry.ListStreamFeatureViewsRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"]\n\x1eListStreamFeatureViewsResponse\x12;\n\x14stream_feature_views\x18\x01 \x03(\x0b\x32\x1d.feast.core.StreamFeatureView\"S\n\x1dGetOnDemandFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xbd\x01\n\x1fListOnDemandFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12G\n\x04tags\x18\x03 \x03(\x0b\x32\x39.feast.registry.ListOnDemandFeatureViewsRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"d\n ListOnDemandFeatureViewsResponse\x12@\n\x17on_demand_feature_views\x18\x01 \x03(\x0b\x32\x1f.feast.core.OnDemandFeatureView\"r\n\x1a\x41pplyFeatureServiceRequest\x12\x33\n\x0f\x66\x65\x61ture_service\x18\x01 \x01(\x0b\x32\x1a.feast.core.FeatureService\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"N\n\x18GetFeatureServiceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xb3\x01\n\x1aListFeatureServicesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x42\n\x04tags\x18\x03 \x03(\x0b\x32\x34.feast.registry.ListFeatureServicesRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"S\n\x1bListFeatureServicesResponse\x12\x34\n\x10\x66\x65\x61ture_services\x18\x01 \x03(\x0b\x32\x1a.feast.core.FeatureService\"L\n\x1b\x44\x65leteFeatureServiceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"l\n\x18\x41pplySavedDatasetRequest\x12/\n\rsaved_dataset\x18\x01 \x01(\x0b\x32\x18.feast.core.SavedDataset\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"L\n\x16GetSavedDatasetRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xaf\x01\n\x18ListSavedDatasetsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12@\n\x04tags\x18\x03 \x03(\x0b\x32\x32.feast.registry.ListSavedDatasetsRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"M\n\x19ListSavedDatasetsResponse\x12\x30\n\x0esaved_datasets\x18\x01 \x03(\x0b\x32\x18.feast.core.SavedDataset\"J\n\x19\x44\x65leteSavedDatasetRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"\x81\x01\n\x1f\x41pplyValidationReferenceRequest\x12=\n\x14validation_reference\x18\x01 \x01(\x0b\x32\x1f.feast.core.ValidationReference\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"S\n\x1dGetValidationReferenceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xbd\x01\n\x1fListValidationReferencesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12G\n\x04tags\x18\x03 \x03(\x0b\x32\x39.feast.registry.ListValidationReferencesRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"b\n ListValidationReferencesResponse\x12>\n\x15validation_references\x18\x01 \x03(\x0b\x32\x1f.feast.core.ValidationReference\"Q\n DeleteValidationReferenceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"e\n\x16\x41pplyPermissionRequest\x12*\n\npermission\x18\x01 \x01(\x0b\x32\x16.feast.core.Permission\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"J\n\x14GetPermissionRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xab\x01\n\x16ListPermissionsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12>\n\x04tags\x18\x03 \x03(\x0b\x32\x30.feast.registry.ListPermissionsRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"F\n\x17ListPermissionsResponse\x12+\n\x0bpermissions\x18\x01 \x03(\x0b\x32\x16.feast.core.Permission\"H\n\x17\x44\x65letePermissionRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"K\n\x13\x41pplyProjectRequest\x12$\n\x07project\x18\x01 \x01(\x0b\x32\x13.feast.core.Project\x12\x0e\n\x06\x63ommit\x18\x02 \x01(\x08\"6\n\x11GetProjectRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\"\x94\x01\n\x13ListProjectsRequest\x12\x13\n\x0b\x61llow_cache\x18\x01 \x01(\x08\x12;\n\x04tags\x18\x02 \x03(\x0b\x32-.feast.registry.ListProjectsRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"=\n\x14ListProjectsResponse\x12%\n\x08projects\x18\x01 \x03(\x0b\x32\x13.feast.core.Project\"4\n\x14\x44\x65leteProjectRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x02 \x01(\x08\"-\n\x0f\x45ntityReference\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"r\n\x0e\x45ntityRelation\x12/\n\x06source\x18\x01 \x01(\x0b\x32\x1f.feast.registry.EntityReference\x12/\n\x06target\x18\x02 \x01(\x0b\x32\x1f.feast.registry.EntityReference\"y\n\x19GetRegistryLineageRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x1a\n\x12\x66ilter_object_type\x18\x03 \x01(\t\x12\x1a\n\x12\x66ilter_object_name\x18\x04 \x01(\t\"\x93\x01\n\x1aGetRegistryLineageResponse\x12\x35\n\rrelationships\x18\x01 \x03(\x0b\x32\x1e.feast.registry.EntityRelation\x12>\n\x16indirect_relationships\x18\x02 \x03(\x0b\x32\x1e.feast.registry.EntityRelation\"\x89\x01\n\x1dGetObjectRelationshipsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0bobject_type\x18\x02 \x01(\t\x12\x13\n\x0bobject_name\x18\x03 \x01(\t\x12\x18\n\x10include_indirect\x18\x04 \x01(\x08\x12\x13\n\x0b\x61llow_cache\x18\x05 \x01(\x08\"W\n\x1eGetObjectRelationshipsResponse\x12\x35\n\rrelationships\x18\x01 \x03(\x0b\x32\x1e.feast.registry.EntityRelation2\xb5\"\n\x0eRegistryServer\x12K\n\x0b\x41pplyEntity\x12\".feast.registry.ApplyEntityRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x43\n\tGetEntity\x12 .feast.registry.GetEntityRequest\x1a\x12.feast.core.Entity\"\x00\x12[\n\x0cListEntities\x12#.feast.registry.ListEntitiesRequest\x1a$.feast.registry.ListEntitiesResponse\"\x00\x12M\n\x0c\x44\x65leteEntity\x12#.feast.registry.DeleteEntityRequest\x1a\x16.google.protobuf.Empty\"\x00\x12S\n\x0f\x41pplyDataSource\x12&.feast.registry.ApplyDataSourceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12O\n\rGetDataSource\x12$.feast.registry.GetDataSourceRequest\x1a\x16.feast.core.DataSource\"\x00\x12\x64\n\x0fListDataSources\x12&.feast.registry.ListDataSourcesRequest\x1a\'.feast.registry.ListDataSourcesResponse\"\x00\x12U\n\x10\x44\x65leteDataSource\x12\'.feast.registry.DeleteDataSourceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12U\n\x10\x41pplyFeatureView\x12\'.feast.registry.ApplyFeatureViewRequest\x1a\x16.google.protobuf.Empty\"\x00\x12W\n\x11\x44\x65leteFeatureView\x12(.feast.registry.DeleteFeatureViewRequest\x1a\x16.google.protobuf.Empty\"\x00\x12j\n\x11GetAnyFeatureView\x12(.feast.registry.GetAnyFeatureViewRequest\x1a).feast.registry.GetAnyFeatureViewResponse\"\x00\x12p\n\x13ListAllFeatureViews\x12*.feast.registry.ListAllFeatureViewsRequest\x1a+.feast.registry.ListAllFeatureViewsResponse\"\x00\x12R\n\x0eGetFeatureView\x12%.feast.registry.GetFeatureViewRequest\x1a\x17.feast.core.FeatureView\"\x00\x12g\n\x10ListFeatureViews\x12\'.feast.registry.ListFeatureViewsRequest\x1a(.feast.registry.ListFeatureViewsResponse\"\x00\x12\x64\n\x14GetStreamFeatureView\x12+.feast.registry.GetStreamFeatureViewRequest\x1a\x1d.feast.core.StreamFeatureView\"\x00\x12y\n\x16ListStreamFeatureViews\x12-.feast.registry.ListStreamFeatureViewsRequest\x1a..feast.registry.ListStreamFeatureViewsResponse\"\x00\x12j\n\x16GetOnDemandFeatureView\x12-.feast.registry.GetOnDemandFeatureViewRequest\x1a\x1f.feast.core.OnDemandFeatureView\"\x00\x12\x7f\n\x18ListOnDemandFeatureViews\x12/.feast.registry.ListOnDemandFeatureViewsRequest\x1a\x30.feast.registry.ListOnDemandFeatureViewsResponse\"\x00\x12[\n\x13\x41pplyFeatureService\x12*.feast.registry.ApplyFeatureServiceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12[\n\x11GetFeatureService\x12(.feast.registry.GetFeatureServiceRequest\x1a\x1a.feast.core.FeatureService\"\x00\x12p\n\x13ListFeatureServices\x12*.feast.registry.ListFeatureServicesRequest\x1a+.feast.registry.ListFeatureServicesResponse\"\x00\x12]\n\x14\x44\x65leteFeatureService\x12+.feast.registry.DeleteFeatureServiceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12W\n\x11\x41pplySavedDataset\x12(.feast.registry.ApplySavedDatasetRequest\x1a\x16.google.protobuf.Empty\"\x00\x12U\n\x0fGetSavedDataset\x12&.feast.registry.GetSavedDatasetRequest\x1a\x18.feast.core.SavedDataset\"\x00\x12j\n\x11ListSavedDatasets\x12(.feast.registry.ListSavedDatasetsRequest\x1a).feast.registry.ListSavedDatasetsResponse\"\x00\x12Y\n\x12\x44\x65leteSavedDataset\x12).feast.registry.DeleteSavedDatasetRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x65\n\x18\x41pplyValidationReference\x12/.feast.registry.ApplyValidationReferenceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12j\n\x16GetValidationReference\x12-.feast.registry.GetValidationReferenceRequest\x1a\x1f.feast.core.ValidationReference\"\x00\x12\x7f\n\x18ListValidationReferences\x12/.feast.registry.ListValidationReferencesRequest\x1a\x30.feast.registry.ListValidationReferencesResponse\"\x00\x12g\n\x19\x44\x65leteValidationReference\x12\x30.feast.registry.DeleteValidationReferenceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12S\n\x0f\x41pplyPermission\x12&.feast.registry.ApplyPermissionRequest\x1a\x16.google.protobuf.Empty\"\x00\x12O\n\rGetPermission\x12$.feast.registry.GetPermissionRequest\x1a\x16.feast.core.Permission\"\x00\x12\x64\n\x0fListPermissions\x12&.feast.registry.ListPermissionsRequest\x1a\'.feast.registry.ListPermissionsResponse\"\x00\x12U\n\x10\x44\x65letePermission\x12\'.feast.registry.DeletePermissionRequest\x1a\x16.google.protobuf.Empty\"\x00\x12M\n\x0c\x41pplyProject\x12#.feast.registry.ApplyProjectRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\nGetProject\x12!.feast.registry.GetProjectRequest\x1a\x13.feast.core.Project\"\x00\x12[\n\x0cListProjects\x12#.feast.registry.ListProjectsRequest\x1a$.feast.registry.ListProjectsResponse\"\x00\x12O\n\rDeleteProject\x12$.feast.registry.DeleteProjectRequest\x1a\x16.google.protobuf.Empty\"\x00\x12]\n\x14\x41pplyMaterialization\x12+.feast.registry.ApplyMaterializationRequest\x1a\x16.google.protobuf.Empty\"\x00\x12p\n\x13ListProjectMetadata\x12*.feast.registry.ListProjectMetadataRequest\x1a+.feast.registry.ListProjectMetadataResponse\"\x00\x12K\n\x0bUpdateInfra\x12\".feast.registry.UpdateInfraRequest\x1a\x16.google.protobuf.Empty\"\x00\x12@\n\x08GetInfra\x12\x1f.feast.registry.GetInfraRequest\x1a\x11.feast.core.Infra\"\x00\x12:\n\x06\x43ommit\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\"\x00\x12\x43\n\x07Refresh\x12\x1e.feast.registry.RefreshRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x37\n\x05Proto\x12\x16.google.protobuf.Empty\x1a\x14.feast.core.Registry\"\x00\x12m\n\x12GetRegistryLineage\x12).feast.registry.GetRegistryLineageRequest\x1a*.feast.registry.GetRegistryLineageResponse\"\x00\x12y\n\x16GetObjectRelationships\x12-.feast.registry.GetObjectRelationshipsRequest\x1a..feast.registry.GetObjectRelationshipsResponse\"\x00\x42\x35Z3github.com/feast-dev/feast/go/protos/feast/registryb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#feast/registry/RegistryServer.proto\x12\x0e\x66\x65\x61st.registry\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19\x66\x65\x61st/core/Registry.proto\x1a\x17\x66\x65\x61st/core/Entity.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\x1a\x1c\x66\x65\x61st/core/FeatureView.proto\x1a\"feast/core/StreamFeatureView.proto\x1a$feast/core/OnDemandFeatureView.proto\x1a\x1f\x66\x65\x61st/core/FeatureService.proto\x1a\x1d\x66\x65\x61st/core/SavedDataset.proto\x1a\"feast/core/ValidationProfile.proto\x1a\x1c\x66\x65\x61st/core/InfraObject.proto\x1a\x1b\x66\x65\x61st/core/Permission.proto\x1a\x18\x66\x65\x61st/core/Project.proto\"/\n\x10PaginationParams\x12\x0c\n\x04page\x18\x01 \x01(\x05\x12\r\n\x05limit\x18\x02 \x01(\x05\"4\n\rSortingParams\x12\x0f\n\x07sort_by\x18\x01 \x01(\t\x12\x12\n\nsort_order\x18\x02 \x01(\t\"\x83\x01\n\x12PaginationMetadata\x12\x0c\n\x04page\x18\x01 \x01(\x05\x12\r\n\x05limit\x18\x02 \x01(\x05\x12\x13\n\x0btotal_count\x18\x03 \x01(\x05\x12\x13\n\x0btotal_pages\x18\x04 \x01(\x05\x12\x10\n\x08has_next\x18\x05 \x01(\x08\x12\x14\n\x0chas_previous\x18\x06 \x01(\x08\"!\n\x0eRefreshRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\"W\n\x12UpdateInfraRequest\x12 \n\x05infra\x18\x01 \x01(\x0b\x32\x11.feast.core.Infra\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"7\n\x0fGetInfraRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\"B\n\x1aListProjectMetadataRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\"T\n\x1bListProjectMetadataResponse\x12\x35\n\x10project_metadata\x18\x01 \x03(\x0b\x32\x1b.feast.core.ProjectMetadata\"\xcb\x01\n\x1b\x41pplyMaterializationRequest\x12-\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureView\x12\x0f\n\x07project\x18\x02 \x01(\t\x12.\n\nstart_date\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_date\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0e\n\x06\x63ommit\x18\x05 \x01(\x08\"Y\n\x12\x41pplyEntityRequest\x12\"\n\x06\x65ntity\x18\x01 \x01(\x0b\x32\x12.feast.core.Entity\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"F\n\x10GetEntityRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x8b\x02\n\x13ListEntitiesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12;\n\x04tags\x18\x03 \x03(\x0b\x32-.feast.registry.ListEntitiesRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"t\n\x14ListEntitiesResponse\x12$\n\x08\x65ntities\x18\x01 \x03(\x0b\x32\x12.feast.core.Entity\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"D\n\x13\x44\x65leteEntityRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"f\n\x16\x41pplyDataSourceRequest\x12+\n\x0b\x64\x61ta_source\x18\x01 \x01(\x0b\x32\x16.feast.core.DataSource\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"J\n\x14GetDataSourceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x91\x02\n\x16ListDataSourcesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12>\n\x04tags\x18\x03 \x03(\x0b\x32\x30.feast.registry.ListDataSourcesRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x7f\n\x17ListDataSourcesResponse\x12,\n\x0c\x64\x61ta_sources\x18\x01 \x03(\x0b\x32\x16.feast.core.DataSource\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"H\n\x17\x44\x65leteDataSourceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"\x81\x02\n\x17\x41pplyFeatureViewRequest\x12/\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureViewH\x00\x12\x41\n\x16on_demand_feature_view\x18\x02 \x01(\x0b\x32\x1f.feast.core.OnDemandFeatureViewH\x00\x12<\n\x13stream_feature_view\x18\x03 \x01(\x0b\x32\x1d.feast.core.StreamFeatureViewH\x00\x12\x0f\n\x07project\x18\x04 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x05 \x01(\x08\x42\x13\n\x11\x62\x61se_feature_view\"K\n\x15GetFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x93\x02\n\x17ListFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12?\n\x04tags\x18\x03 \x03(\x0b\x32\x31.feast.registry.ListFeatureViewsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x82\x01\n\x18ListFeatureViewsResponse\x12.\n\rfeature_views\x18\x01 \x03(\x0b\x32\x17.feast.core.FeatureView\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"I\n\x18\x44\x65leteFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"\xd6\x01\n\x0e\x41nyFeatureView\x12/\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureViewH\x00\x12\x41\n\x16on_demand_feature_view\x18\x02 \x01(\x0b\x32\x1f.feast.core.OnDemandFeatureViewH\x00\x12<\n\x13stream_feature_view\x18\x03 \x01(\x0b\x32\x1d.feast.core.StreamFeatureViewH\x00\x42\x12\n\x10\x61ny_feature_view\"N\n\x18GetAnyFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"U\n\x19GetAnyFeatureViewResponse\x12\x38\n\x10\x61ny_feature_view\x18\x01 \x01(\x0b\x32\x1e.feast.registry.AnyFeatureView\"\x99\x02\n\x1aListAllFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x42\n\x04tags\x18\x03 \x03(\x0b\x32\x34.feast.registry.ListAllFeatureViewsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x8c\x01\n\x1bListAllFeatureViewsResponse\x12\x35\n\rfeature_views\x18\x01 \x03(\x0b\x32\x1e.feast.registry.AnyFeatureView\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"Q\n\x1bGetStreamFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x9f\x02\n\x1dListStreamFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x45\n\x04tags\x18\x03 \x03(\x0b\x32\x37.feast.registry.ListStreamFeatureViewsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x95\x01\n\x1eListStreamFeatureViewsResponse\x12;\n\x14stream_feature_views\x18\x01 \x03(\x0b\x32\x1d.feast.core.StreamFeatureView\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"S\n\x1dGetOnDemandFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xa3\x02\n\x1fListOnDemandFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12G\n\x04tags\x18\x03 \x03(\x0b\x32\x39.feast.registry.ListOnDemandFeatureViewsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x9c\x01\n ListOnDemandFeatureViewsResponse\x12@\n\x17on_demand_feature_views\x18\x01 \x03(\x0b\x32\x1f.feast.core.OnDemandFeatureView\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"r\n\x1a\x41pplyFeatureServiceRequest\x12\x33\n\x0f\x66\x65\x61ture_service\x18\x01 \x01(\x0b\x32\x1a.feast.core.FeatureService\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"N\n\x18GetFeatureServiceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x99\x02\n\x1aListFeatureServicesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x42\n\x04tags\x18\x03 \x03(\x0b\x32\x34.feast.registry.ListFeatureServicesRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x8b\x01\n\x1bListFeatureServicesResponse\x12\x34\n\x10\x66\x65\x61ture_services\x18\x01 \x03(\x0b\x32\x1a.feast.core.FeatureService\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"L\n\x1b\x44\x65leteFeatureServiceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"l\n\x18\x41pplySavedDatasetRequest\x12/\n\rsaved_dataset\x18\x01 \x01(\x0b\x32\x18.feast.core.SavedDataset\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"L\n\x16GetSavedDatasetRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x95\x02\n\x18ListSavedDatasetsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12@\n\x04tags\x18\x03 \x03(\x0b\x32\x32.feast.registry.ListSavedDatasetsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x85\x01\n\x19ListSavedDatasetsResponse\x12\x30\n\x0esaved_datasets\x18\x01 \x03(\x0b\x32\x18.feast.core.SavedDataset\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"J\n\x19\x44\x65leteSavedDatasetRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"\x81\x01\n\x1f\x41pplyValidationReferenceRequest\x12=\n\x14validation_reference\x18\x01 \x01(\x0b\x32\x1f.feast.core.ValidationReference\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"S\n\x1dGetValidationReferenceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xa3\x02\n\x1fListValidationReferencesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12G\n\x04tags\x18\x03 \x03(\x0b\x32\x39.feast.registry.ListValidationReferencesRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x9a\x01\n ListValidationReferencesResponse\x12>\n\x15validation_references\x18\x01 \x03(\x0b\x32\x1f.feast.core.ValidationReference\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"Q\n DeleteValidationReferenceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"e\n\x16\x41pplyPermissionRequest\x12*\n\npermission\x18\x01 \x01(\x0b\x32\x16.feast.core.Permission\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"J\n\x14GetPermissionRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x91\x02\n\x16ListPermissionsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12>\n\x04tags\x18\x03 \x03(\x0b\x32\x30.feast.registry.ListPermissionsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"~\n\x17ListPermissionsResponse\x12+\n\x0bpermissions\x18\x01 \x03(\x0b\x32\x16.feast.core.Permission\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"H\n\x17\x44\x65letePermissionRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"K\n\x13\x41pplyProjectRequest\x12$\n\x07project\x18\x01 \x01(\x0b\x32\x13.feast.core.Project\x12\x0e\n\x06\x63ommit\x18\x02 \x01(\x08\"6\n\x11GetProjectRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\"\xfa\x01\n\x13ListProjectsRequest\x12\x13\n\x0b\x61llow_cache\x18\x01 \x01(\x08\x12;\n\x04tags\x18\x02 \x03(\x0b\x32-.feast.registry.ListProjectsRequest.TagsEntry\x12\x34\n\npagination\x18\x03 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x04 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"u\n\x14ListProjectsResponse\x12%\n\x08projects\x18\x01 \x03(\x0b\x32\x13.feast.core.Project\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"4\n\x14\x44\x65leteProjectRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x02 \x01(\x08\"-\n\x0f\x45ntityReference\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"r\n\x0e\x45ntityRelation\x12/\n\x06source\x18\x01 \x01(\x0b\x32\x1f.feast.registry.EntityReference\x12/\n\x06target\x18\x02 \x01(\x0b\x32\x1f.feast.registry.EntityReference\"\xdf\x01\n\x19GetRegistryLineageRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x1a\n\x12\x66ilter_object_type\x18\x03 \x01(\t\x12\x1a\n\x12\x66ilter_object_name\x18\x04 \x01(\t\x12\x34\n\npagination\x18\x05 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x06 \x01(\x0b\x32\x1d.feast.registry.SortingParams\"\xa8\x02\n\x1aGetRegistryLineageResponse\x12\x35\n\rrelationships\x18\x01 \x03(\x0b\x32\x1e.feast.registry.EntityRelation\x12>\n\x16indirect_relationships\x18\x02 \x03(\x0b\x32\x1e.feast.registry.EntityRelation\x12\x44\n\x18relationships_pagination\x18\x03 \x01(\x0b\x32\".feast.registry.PaginationMetadata\x12M\n!indirect_relationships_pagination\x18\x04 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"\xef\x01\n\x1dGetObjectRelationshipsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0bobject_type\x18\x02 \x01(\t\x12\x13\n\x0bobject_name\x18\x03 \x01(\t\x12\x18\n\x10include_indirect\x18\x04 \x01(\x08\x12\x13\n\x0b\x61llow_cache\x18\x05 \x01(\x08\x12\x34\n\npagination\x18\x06 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x07 \x01(\x0b\x32\x1d.feast.registry.SortingParams\"\x8f\x01\n\x1eGetObjectRelationshipsResponse\x12\x35\n\rrelationships\x18\x01 \x03(\x0b\x32\x1e.feast.registry.EntityRelation\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata2\xb5\"\n\x0eRegistryServer\x12K\n\x0b\x41pplyEntity\x12\".feast.registry.ApplyEntityRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x43\n\tGetEntity\x12 .feast.registry.GetEntityRequest\x1a\x12.feast.core.Entity\"\x00\x12[\n\x0cListEntities\x12#.feast.registry.ListEntitiesRequest\x1a$.feast.registry.ListEntitiesResponse\"\x00\x12M\n\x0c\x44\x65leteEntity\x12#.feast.registry.DeleteEntityRequest\x1a\x16.google.protobuf.Empty\"\x00\x12S\n\x0f\x41pplyDataSource\x12&.feast.registry.ApplyDataSourceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12O\n\rGetDataSource\x12$.feast.registry.GetDataSourceRequest\x1a\x16.feast.core.DataSource\"\x00\x12\x64\n\x0fListDataSources\x12&.feast.registry.ListDataSourcesRequest\x1a\'.feast.registry.ListDataSourcesResponse\"\x00\x12U\n\x10\x44\x65leteDataSource\x12\'.feast.registry.DeleteDataSourceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12U\n\x10\x41pplyFeatureView\x12\'.feast.registry.ApplyFeatureViewRequest\x1a\x16.google.protobuf.Empty\"\x00\x12W\n\x11\x44\x65leteFeatureView\x12(.feast.registry.DeleteFeatureViewRequest\x1a\x16.google.protobuf.Empty\"\x00\x12j\n\x11GetAnyFeatureView\x12(.feast.registry.GetAnyFeatureViewRequest\x1a).feast.registry.GetAnyFeatureViewResponse\"\x00\x12p\n\x13ListAllFeatureViews\x12*.feast.registry.ListAllFeatureViewsRequest\x1a+.feast.registry.ListAllFeatureViewsResponse\"\x00\x12R\n\x0eGetFeatureView\x12%.feast.registry.GetFeatureViewRequest\x1a\x17.feast.core.FeatureView\"\x00\x12g\n\x10ListFeatureViews\x12\'.feast.registry.ListFeatureViewsRequest\x1a(.feast.registry.ListFeatureViewsResponse\"\x00\x12\x64\n\x14GetStreamFeatureView\x12+.feast.registry.GetStreamFeatureViewRequest\x1a\x1d.feast.core.StreamFeatureView\"\x00\x12y\n\x16ListStreamFeatureViews\x12-.feast.registry.ListStreamFeatureViewsRequest\x1a..feast.registry.ListStreamFeatureViewsResponse\"\x00\x12j\n\x16GetOnDemandFeatureView\x12-.feast.registry.GetOnDemandFeatureViewRequest\x1a\x1f.feast.core.OnDemandFeatureView\"\x00\x12\x7f\n\x18ListOnDemandFeatureViews\x12/.feast.registry.ListOnDemandFeatureViewsRequest\x1a\x30.feast.registry.ListOnDemandFeatureViewsResponse\"\x00\x12[\n\x13\x41pplyFeatureService\x12*.feast.registry.ApplyFeatureServiceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12[\n\x11GetFeatureService\x12(.feast.registry.GetFeatureServiceRequest\x1a\x1a.feast.core.FeatureService\"\x00\x12p\n\x13ListFeatureServices\x12*.feast.registry.ListFeatureServicesRequest\x1a+.feast.registry.ListFeatureServicesResponse\"\x00\x12]\n\x14\x44\x65leteFeatureService\x12+.feast.registry.DeleteFeatureServiceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12W\n\x11\x41pplySavedDataset\x12(.feast.registry.ApplySavedDatasetRequest\x1a\x16.google.protobuf.Empty\"\x00\x12U\n\x0fGetSavedDataset\x12&.feast.registry.GetSavedDatasetRequest\x1a\x18.feast.core.SavedDataset\"\x00\x12j\n\x11ListSavedDatasets\x12(.feast.registry.ListSavedDatasetsRequest\x1a).feast.registry.ListSavedDatasetsResponse\"\x00\x12Y\n\x12\x44\x65leteSavedDataset\x12).feast.registry.DeleteSavedDatasetRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x65\n\x18\x41pplyValidationReference\x12/.feast.registry.ApplyValidationReferenceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12j\n\x16GetValidationReference\x12-.feast.registry.GetValidationReferenceRequest\x1a\x1f.feast.core.ValidationReference\"\x00\x12\x7f\n\x18ListValidationReferences\x12/.feast.registry.ListValidationReferencesRequest\x1a\x30.feast.registry.ListValidationReferencesResponse\"\x00\x12g\n\x19\x44\x65leteValidationReference\x12\x30.feast.registry.DeleteValidationReferenceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12S\n\x0f\x41pplyPermission\x12&.feast.registry.ApplyPermissionRequest\x1a\x16.google.protobuf.Empty\"\x00\x12O\n\rGetPermission\x12$.feast.registry.GetPermissionRequest\x1a\x16.feast.core.Permission\"\x00\x12\x64\n\x0fListPermissions\x12&.feast.registry.ListPermissionsRequest\x1a\'.feast.registry.ListPermissionsResponse\"\x00\x12U\n\x10\x44\x65letePermission\x12\'.feast.registry.DeletePermissionRequest\x1a\x16.google.protobuf.Empty\"\x00\x12M\n\x0c\x41pplyProject\x12#.feast.registry.ApplyProjectRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\nGetProject\x12!.feast.registry.GetProjectRequest\x1a\x13.feast.core.Project\"\x00\x12[\n\x0cListProjects\x12#.feast.registry.ListProjectsRequest\x1a$.feast.registry.ListProjectsResponse\"\x00\x12O\n\rDeleteProject\x12$.feast.registry.DeleteProjectRequest\x1a\x16.google.protobuf.Empty\"\x00\x12]\n\x14\x41pplyMaterialization\x12+.feast.registry.ApplyMaterializationRequest\x1a\x16.google.protobuf.Empty\"\x00\x12p\n\x13ListProjectMetadata\x12*.feast.registry.ListProjectMetadataRequest\x1a+.feast.registry.ListProjectMetadataResponse\"\x00\x12K\n\x0bUpdateInfra\x12\".feast.registry.UpdateInfraRequest\x1a\x16.google.protobuf.Empty\"\x00\x12@\n\x08GetInfra\x12\x1f.feast.registry.GetInfraRequest\x1a\x11.feast.core.Infra\"\x00\x12:\n\x06\x43ommit\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\"\x00\x12\x43\n\x07Refresh\x12\x1e.feast.registry.RefreshRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x37\n\x05Proto\x12\x16.google.protobuf.Empty\x1a\x14.feast.core.Registry\"\x00\x12m\n\x12GetRegistryLineage\x12).feast.registry.GetRegistryLineageRequest\x1a*.feast.registry.GetRegistryLineageResponse\"\x00\x12y\n\x16GetObjectRelationships\x12-.feast.registry.GetObjectRelationshipsRequest\x1a..feast.registry.GetObjectRelationshipsResponse\"\x00\x42\x35Z3github.com/feast-dev/feast/go/protos/feast/registryb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -58,154 +58,160 @@ _globals['_LISTPERMISSIONSREQUEST_TAGSENTRY']._serialized_options = b'8\001' _globals['_LISTPROJECTSREQUEST_TAGSENTRY']._options = None _globals['_LISTPROJECTSREQUEST_TAGSENTRY']._serialized_options = b'8\001' - _globals['_REFRESHREQUEST']._serialized_start=487 - _globals['_REFRESHREQUEST']._serialized_end=520 - _globals['_UPDATEINFRAREQUEST']._serialized_start=522 - _globals['_UPDATEINFRAREQUEST']._serialized_end=609 - _globals['_GETINFRAREQUEST']._serialized_start=611 - _globals['_GETINFRAREQUEST']._serialized_end=666 - _globals['_LISTPROJECTMETADATAREQUEST']._serialized_start=668 - _globals['_LISTPROJECTMETADATAREQUEST']._serialized_end=734 - _globals['_LISTPROJECTMETADATARESPONSE']._serialized_start=736 - _globals['_LISTPROJECTMETADATARESPONSE']._serialized_end=820 - _globals['_APPLYMATERIALIZATIONREQUEST']._serialized_start=823 - _globals['_APPLYMATERIALIZATIONREQUEST']._serialized_end=1026 - _globals['_APPLYENTITYREQUEST']._serialized_start=1028 - _globals['_APPLYENTITYREQUEST']._serialized_end=1117 - _globals['_GETENTITYREQUEST']._serialized_start=1119 - _globals['_GETENTITYREQUEST']._serialized_end=1189 - _globals['_LISTENTITIESREQUEST']._serialized_start=1192 - _globals['_LISTENTITIESREQUEST']._serialized_end=1357 - _globals['_LISTENTITIESREQUEST_TAGSENTRY']._serialized_start=1314 - _globals['_LISTENTITIESREQUEST_TAGSENTRY']._serialized_end=1357 - _globals['_LISTENTITIESRESPONSE']._serialized_start=1359 - _globals['_LISTENTITIESRESPONSE']._serialized_end=1419 - _globals['_DELETEENTITYREQUEST']._serialized_start=1421 - _globals['_DELETEENTITYREQUEST']._serialized_end=1489 - _globals['_APPLYDATASOURCEREQUEST']._serialized_start=1491 - _globals['_APPLYDATASOURCEREQUEST']._serialized_end=1593 - _globals['_GETDATASOURCEREQUEST']._serialized_start=1595 - _globals['_GETDATASOURCEREQUEST']._serialized_end=1669 - _globals['_LISTDATASOURCESREQUEST']._serialized_start=1672 - _globals['_LISTDATASOURCESREQUEST']._serialized_end=1843 - _globals['_LISTDATASOURCESREQUEST_TAGSENTRY']._serialized_start=1314 - _globals['_LISTDATASOURCESREQUEST_TAGSENTRY']._serialized_end=1357 - _globals['_LISTDATASOURCESRESPONSE']._serialized_start=1845 - _globals['_LISTDATASOURCESRESPONSE']._serialized_end=1916 - _globals['_DELETEDATASOURCEREQUEST']._serialized_start=1918 - _globals['_DELETEDATASOURCEREQUEST']._serialized_end=1990 - _globals['_APPLYFEATUREVIEWREQUEST']._serialized_start=1993 - _globals['_APPLYFEATUREVIEWREQUEST']._serialized_end=2250 - _globals['_GETFEATUREVIEWREQUEST']._serialized_start=2252 - _globals['_GETFEATUREVIEWREQUEST']._serialized_end=2327 - _globals['_LISTFEATUREVIEWSREQUEST']._serialized_start=2330 - _globals['_LISTFEATUREVIEWSREQUEST']._serialized_end=2503 - _globals['_LISTFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1314 - _globals['_LISTFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1357 - _globals['_LISTFEATUREVIEWSRESPONSE']._serialized_start=2505 - _globals['_LISTFEATUREVIEWSRESPONSE']._serialized_end=2579 - _globals['_DELETEFEATUREVIEWREQUEST']._serialized_start=2581 - _globals['_DELETEFEATUREVIEWREQUEST']._serialized_end=2654 - _globals['_ANYFEATUREVIEW']._serialized_start=2657 - _globals['_ANYFEATUREVIEW']._serialized_end=2871 - _globals['_GETANYFEATUREVIEWREQUEST']._serialized_start=2873 - _globals['_GETANYFEATUREVIEWREQUEST']._serialized_end=2951 - _globals['_GETANYFEATUREVIEWRESPONSE']._serialized_start=2953 - _globals['_GETANYFEATUREVIEWRESPONSE']._serialized_end=3038 - _globals['_LISTALLFEATUREVIEWSREQUEST']._serialized_start=3041 - _globals['_LISTALLFEATUREVIEWSREQUEST']._serialized_end=3220 - _globals['_LISTALLFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1314 - _globals['_LISTALLFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1357 - _globals['_LISTALLFEATUREVIEWSRESPONSE']._serialized_start=3222 - _globals['_LISTALLFEATUREVIEWSRESPONSE']._serialized_end=3306 - _globals['_GETSTREAMFEATUREVIEWREQUEST']._serialized_start=3308 - _globals['_GETSTREAMFEATUREVIEWREQUEST']._serialized_end=3389 - _globals['_LISTSTREAMFEATUREVIEWSREQUEST']._serialized_start=3392 - _globals['_LISTSTREAMFEATUREVIEWSREQUEST']._serialized_end=3577 - _globals['_LISTSTREAMFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1314 - _globals['_LISTSTREAMFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1357 - _globals['_LISTSTREAMFEATUREVIEWSRESPONSE']._serialized_start=3579 - _globals['_LISTSTREAMFEATUREVIEWSRESPONSE']._serialized_end=3672 - _globals['_GETONDEMANDFEATUREVIEWREQUEST']._serialized_start=3674 - _globals['_GETONDEMANDFEATUREVIEWREQUEST']._serialized_end=3757 - _globals['_LISTONDEMANDFEATUREVIEWSREQUEST']._serialized_start=3760 - _globals['_LISTONDEMANDFEATUREVIEWSREQUEST']._serialized_end=3949 - _globals['_LISTONDEMANDFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1314 - _globals['_LISTONDEMANDFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1357 - _globals['_LISTONDEMANDFEATUREVIEWSRESPONSE']._serialized_start=3951 - _globals['_LISTONDEMANDFEATUREVIEWSRESPONSE']._serialized_end=4051 - _globals['_APPLYFEATURESERVICEREQUEST']._serialized_start=4053 - _globals['_APPLYFEATURESERVICEREQUEST']._serialized_end=4167 - _globals['_GETFEATURESERVICEREQUEST']._serialized_start=4169 - _globals['_GETFEATURESERVICEREQUEST']._serialized_end=4247 - _globals['_LISTFEATURESERVICESREQUEST']._serialized_start=4250 - _globals['_LISTFEATURESERVICESREQUEST']._serialized_end=4429 - _globals['_LISTFEATURESERVICESREQUEST_TAGSENTRY']._serialized_start=1314 - _globals['_LISTFEATURESERVICESREQUEST_TAGSENTRY']._serialized_end=1357 - _globals['_LISTFEATURESERVICESRESPONSE']._serialized_start=4431 - _globals['_LISTFEATURESERVICESRESPONSE']._serialized_end=4514 - _globals['_DELETEFEATURESERVICEREQUEST']._serialized_start=4516 - _globals['_DELETEFEATURESERVICEREQUEST']._serialized_end=4592 - _globals['_APPLYSAVEDDATASETREQUEST']._serialized_start=4594 - _globals['_APPLYSAVEDDATASETREQUEST']._serialized_end=4702 - _globals['_GETSAVEDDATASETREQUEST']._serialized_start=4704 - _globals['_GETSAVEDDATASETREQUEST']._serialized_end=4780 - _globals['_LISTSAVEDDATASETSREQUEST']._serialized_start=4783 - _globals['_LISTSAVEDDATASETSREQUEST']._serialized_end=4958 - _globals['_LISTSAVEDDATASETSREQUEST_TAGSENTRY']._serialized_start=1314 - _globals['_LISTSAVEDDATASETSREQUEST_TAGSENTRY']._serialized_end=1357 - _globals['_LISTSAVEDDATASETSRESPONSE']._serialized_start=4960 - _globals['_LISTSAVEDDATASETSRESPONSE']._serialized_end=5037 - _globals['_DELETESAVEDDATASETREQUEST']._serialized_start=5039 - _globals['_DELETESAVEDDATASETREQUEST']._serialized_end=5113 - _globals['_APPLYVALIDATIONREFERENCEREQUEST']._serialized_start=5116 - _globals['_APPLYVALIDATIONREFERENCEREQUEST']._serialized_end=5245 - _globals['_GETVALIDATIONREFERENCEREQUEST']._serialized_start=5247 - _globals['_GETVALIDATIONREFERENCEREQUEST']._serialized_end=5330 - _globals['_LISTVALIDATIONREFERENCESREQUEST']._serialized_start=5333 - _globals['_LISTVALIDATIONREFERENCESREQUEST']._serialized_end=5522 - _globals['_LISTVALIDATIONREFERENCESREQUEST_TAGSENTRY']._serialized_start=1314 - _globals['_LISTVALIDATIONREFERENCESREQUEST_TAGSENTRY']._serialized_end=1357 - _globals['_LISTVALIDATIONREFERENCESRESPONSE']._serialized_start=5524 - _globals['_LISTVALIDATIONREFERENCESRESPONSE']._serialized_end=5622 - _globals['_DELETEVALIDATIONREFERENCEREQUEST']._serialized_start=5624 - _globals['_DELETEVALIDATIONREFERENCEREQUEST']._serialized_end=5705 - _globals['_APPLYPERMISSIONREQUEST']._serialized_start=5707 - _globals['_APPLYPERMISSIONREQUEST']._serialized_end=5808 - _globals['_GETPERMISSIONREQUEST']._serialized_start=5810 - _globals['_GETPERMISSIONREQUEST']._serialized_end=5884 - _globals['_LISTPERMISSIONSREQUEST']._serialized_start=5887 - _globals['_LISTPERMISSIONSREQUEST']._serialized_end=6058 - _globals['_LISTPERMISSIONSREQUEST_TAGSENTRY']._serialized_start=1314 - _globals['_LISTPERMISSIONSREQUEST_TAGSENTRY']._serialized_end=1357 - _globals['_LISTPERMISSIONSRESPONSE']._serialized_start=6060 - _globals['_LISTPERMISSIONSRESPONSE']._serialized_end=6130 - _globals['_DELETEPERMISSIONREQUEST']._serialized_start=6132 - _globals['_DELETEPERMISSIONREQUEST']._serialized_end=6204 - _globals['_APPLYPROJECTREQUEST']._serialized_start=6206 - _globals['_APPLYPROJECTREQUEST']._serialized_end=6281 - _globals['_GETPROJECTREQUEST']._serialized_start=6283 - _globals['_GETPROJECTREQUEST']._serialized_end=6337 - _globals['_LISTPROJECTSREQUEST']._serialized_start=6340 - _globals['_LISTPROJECTSREQUEST']._serialized_end=6488 - _globals['_LISTPROJECTSREQUEST_TAGSENTRY']._serialized_start=1314 - _globals['_LISTPROJECTSREQUEST_TAGSENTRY']._serialized_end=1357 - _globals['_LISTPROJECTSRESPONSE']._serialized_start=6490 - _globals['_LISTPROJECTSRESPONSE']._serialized_end=6551 - _globals['_DELETEPROJECTREQUEST']._serialized_start=6553 - _globals['_DELETEPROJECTREQUEST']._serialized_end=6605 - _globals['_ENTITYREFERENCE']._serialized_start=6607 - _globals['_ENTITYREFERENCE']._serialized_end=6652 - _globals['_ENTITYRELATION']._serialized_start=6654 - _globals['_ENTITYRELATION']._serialized_end=6768 - _globals['_GETREGISTRYLINEAGEREQUEST']._serialized_start=6770 - _globals['_GETREGISTRYLINEAGEREQUEST']._serialized_end=6891 - _globals['_GETREGISTRYLINEAGERESPONSE']._serialized_start=6894 - _globals['_GETREGISTRYLINEAGERESPONSE']._serialized_end=7041 - _globals['_GETOBJECTRELATIONSHIPSREQUEST']._serialized_start=7044 - _globals['_GETOBJECTRELATIONSHIPSREQUEST']._serialized_end=7181 - _globals['_GETOBJECTRELATIONSHIPSRESPONSE']._serialized_start=7183 - _globals['_GETOBJECTRELATIONSHIPSRESPONSE']._serialized_end=7270 - _globals['_REGISTRYSERVER']._serialized_start=7273 - _globals['_REGISTRYSERVER']._serialized_end=11678 + _globals['_PAGINATIONPARAMS']._serialized_start=487 + _globals['_PAGINATIONPARAMS']._serialized_end=534 + _globals['_SORTINGPARAMS']._serialized_start=536 + _globals['_SORTINGPARAMS']._serialized_end=588 + _globals['_PAGINATIONMETADATA']._serialized_start=591 + _globals['_PAGINATIONMETADATA']._serialized_end=722 + _globals['_REFRESHREQUEST']._serialized_start=724 + _globals['_REFRESHREQUEST']._serialized_end=757 + _globals['_UPDATEINFRAREQUEST']._serialized_start=759 + _globals['_UPDATEINFRAREQUEST']._serialized_end=846 + _globals['_GETINFRAREQUEST']._serialized_start=848 + _globals['_GETINFRAREQUEST']._serialized_end=903 + _globals['_LISTPROJECTMETADATAREQUEST']._serialized_start=905 + _globals['_LISTPROJECTMETADATAREQUEST']._serialized_end=971 + _globals['_LISTPROJECTMETADATARESPONSE']._serialized_start=973 + _globals['_LISTPROJECTMETADATARESPONSE']._serialized_end=1057 + _globals['_APPLYMATERIALIZATIONREQUEST']._serialized_start=1060 + _globals['_APPLYMATERIALIZATIONREQUEST']._serialized_end=1263 + _globals['_APPLYENTITYREQUEST']._serialized_start=1265 + _globals['_APPLYENTITYREQUEST']._serialized_end=1354 + _globals['_GETENTITYREQUEST']._serialized_start=1356 + _globals['_GETENTITYREQUEST']._serialized_end=1426 + _globals['_LISTENTITIESREQUEST']._serialized_start=1429 + _globals['_LISTENTITIESREQUEST']._serialized_end=1696 + _globals['_LISTENTITIESREQUEST_TAGSENTRY']._serialized_start=1653 + _globals['_LISTENTITIESREQUEST_TAGSENTRY']._serialized_end=1696 + _globals['_LISTENTITIESRESPONSE']._serialized_start=1698 + _globals['_LISTENTITIESRESPONSE']._serialized_end=1814 + _globals['_DELETEENTITYREQUEST']._serialized_start=1816 + _globals['_DELETEENTITYREQUEST']._serialized_end=1884 + _globals['_APPLYDATASOURCEREQUEST']._serialized_start=1886 + _globals['_APPLYDATASOURCEREQUEST']._serialized_end=1988 + _globals['_GETDATASOURCEREQUEST']._serialized_start=1990 + _globals['_GETDATASOURCEREQUEST']._serialized_end=2064 + _globals['_LISTDATASOURCESREQUEST']._serialized_start=2067 + _globals['_LISTDATASOURCESREQUEST']._serialized_end=2340 + _globals['_LISTDATASOURCESREQUEST_TAGSENTRY']._serialized_start=1653 + _globals['_LISTDATASOURCESREQUEST_TAGSENTRY']._serialized_end=1696 + _globals['_LISTDATASOURCESRESPONSE']._serialized_start=2342 + _globals['_LISTDATASOURCESRESPONSE']._serialized_end=2469 + _globals['_DELETEDATASOURCEREQUEST']._serialized_start=2471 + _globals['_DELETEDATASOURCEREQUEST']._serialized_end=2543 + _globals['_APPLYFEATUREVIEWREQUEST']._serialized_start=2546 + _globals['_APPLYFEATUREVIEWREQUEST']._serialized_end=2803 + _globals['_GETFEATUREVIEWREQUEST']._serialized_start=2805 + _globals['_GETFEATUREVIEWREQUEST']._serialized_end=2880 + _globals['_LISTFEATUREVIEWSREQUEST']._serialized_start=2883 + _globals['_LISTFEATUREVIEWSREQUEST']._serialized_end=3158 + _globals['_LISTFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1653 + _globals['_LISTFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1696 + _globals['_LISTFEATUREVIEWSRESPONSE']._serialized_start=3161 + _globals['_LISTFEATUREVIEWSRESPONSE']._serialized_end=3291 + _globals['_DELETEFEATUREVIEWREQUEST']._serialized_start=3293 + _globals['_DELETEFEATUREVIEWREQUEST']._serialized_end=3366 + _globals['_ANYFEATUREVIEW']._serialized_start=3369 + _globals['_ANYFEATUREVIEW']._serialized_end=3583 + _globals['_GETANYFEATUREVIEWREQUEST']._serialized_start=3585 + _globals['_GETANYFEATUREVIEWREQUEST']._serialized_end=3663 + _globals['_GETANYFEATUREVIEWRESPONSE']._serialized_start=3665 + _globals['_GETANYFEATUREVIEWRESPONSE']._serialized_end=3750 + _globals['_LISTALLFEATUREVIEWSREQUEST']._serialized_start=3753 + _globals['_LISTALLFEATUREVIEWSREQUEST']._serialized_end=4034 + _globals['_LISTALLFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1653 + _globals['_LISTALLFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1696 + _globals['_LISTALLFEATUREVIEWSRESPONSE']._serialized_start=4037 + _globals['_LISTALLFEATUREVIEWSRESPONSE']._serialized_end=4177 + _globals['_GETSTREAMFEATUREVIEWREQUEST']._serialized_start=4179 + _globals['_GETSTREAMFEATUREVIEWREQUEST']._serialized_end=4260 + _globals['_LISTSTREAMFEATUREVIEWSREQUEST']._serialized_start=4263 + _globals['_LISTSTREAMFEATUREVIEWSREQUEST']._serialized_end=4550 + _globals['_LISTSTREAMFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1653 + _globals['_LISTSTREAMFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1696 + _globals['_LISTSTREAMFEATUREVIEWSRESPONSE']._serialized_start=4553 + _globals['_LISTSTREAMFEATUREVIEWSRESPONSE']._serialized_end=4702 + _globals['_GETONDEMANDFEATUREVIEWREQUEST']._serialized_start=4704 + _globals['_GETONDEMANDFEATUREVIEWREQUEST']._serialized_end=4787 + _globals['_LISTONDEMANDFEATUREVIEWSREQUEST']._serialized_start=4790 + _globals['_LISTONDEMANDFEATUREVIEWSREQUEST']._serialized_end=5081 + _globals['_LISTONDEMANDFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1653 + _globals['_LISTONDEMANDFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1696 + _globals['_LISTONDEMANDFEATUREVIEWSRESPONSE']._serialized_start=5084 + _globals['_LISTONDEMANDFEATUREVIEWSRESPONSE']._serialized_end=5240 + _globals['_APPLYFEATURESERVICEREQUEST']._serialized_start=5242 + _globals['_APPLYFEATURESERVICEREQUEST']._serialized_end=5356 + _globals['_GETFEATURESERVICEREQUEST']._serialized_start=5358 + _globals['_GETFEATURESERVICEREQUEST']._serialized_end=5436 + _globals['_LISTFEATURESERVICESREQUEST']._serialized_start=5439 + _globals['_LISTFEATURESERVICESREQUEST']._serialized_end=5720 + _globals['_LISTFEATURESERVICESREQUEST_TAGSENTRY']._serialized_start=1653 + _globals['_LISTFEATURESERVICESREQUEST_TAGSENTRY']._serialized_end=1696 + _globals['_LISTFEATURESERVICESRESPONSE']._serialized_start=5723 + _globals['_LISTFEATURESERVICESRESPONSE']._serialized_end=5862 + _globals['_DELETEFEATURESERVICEREQUEST']._serialized_start=5864 + _globals['_DELETEFEATURESERVICEREQUEST']._serialized_end=5940 + _globals['_APPLYSAVEDDATASETREQUEST']._serialized_start=5942 + _globals['_APPLYSAVEDDATASETREQUEST']._serialized_end=6050 + _globals['_GETSAVEDDATASETREQUEST']._serialized_start=6052 + _globals['_GETSAVEDDATASETREQUEST']._serialized_end=6128 + _globals['_LISTSAVEDDATASETSREQUEST']._serialized_start=6131 + _globals['_LISTSAVEDDATASETSREQUEST']._serialized_end=6408 + _globals['_LISTSAVEDDATASETSREQUEST_TAGSENTRY']._serialized_start=1653 + _globals['_LISTSAVEDDATASETSREQUEST_TAGSENTRY']._serialized_end=1696 + _globals['_LISTSAVEDDATASETSRESPONSE']._serialized_start=6411 + _globals['_LISTSAVEDDATASETSRESPONSE']._serialized_end=6544 + _globals['_DELETESAVEDDATASETREQUEST']._serialized_start=6546 + _globals['_DELETESAVEDDATASETREQUEST']._serialized_end=6620 + _globals['_APPLYVALIDATIONREFERENCEREQUEST']._serialized_start=6623 + _globals['_APPLYVALIDATIONREFERENCEREQUEST']._serialized_end=6752 + _globals['_GETVALIDATIONREFERENCEREQUEST']._serialized_start=6754 + _globals['_GETVALIDATIONREFERENCEREQUEST']._serialized_end=6837 + _globals['_LISTVALIDATIONREFERENCESREQUEST']._serialized_start=6840 + _globals['_LISTVALIDATIONREFERENCESREQUEST']._serialized_end=7131 + _globals['_LISTVALIDATIONREFERENCESREQUEST_TAGSENTRY']._serialized_start=1653 + _globals['_LISTVALIDATIONREFERENCESREQUEST_TAGSENTRY']._serialized_end=1696 + _globals['_LISTVALIDATIONREFERENCESRESPONSE']._serialized_start=7134 + _globals['_LISTVALIDATIONREFERENCESRESPONSE']._serialized_end=7288 + _globals['_DELETEVALIDATIONREFERENCEREQUEST']._serialized_start=7290 + _globals['_DELETEVALIDATIONREFERENCEREQUEST']._serialized_end=7371 + _globals['_APPLYPERMISSIONREQUEST']._serialized_start=7373 + _globals['_APPLYPERMISSIONREQUEST']._serialized_end=7474 + _globals['_GETPERMISSIONREQUEST']._serialized_start=7476 + _globals['_GETPERMISSIONREQUEST']._serialized_end=7550 + _globals['_LISTPERMISSIONSREQUEST']._serialized_start=7553 + _globals['_LISTPERMISSIONSREQUEST']._serialized_end=7826 + _globals['_LISTPERMISSIONSREQUEST_TAGSENTRY']._serialized_start=1653 + _globals['_LISTPERMISSIONSREQUEST_TAGSENTRY']._serialized_end=1696 + _globals['_LISTPERMISSIONSRESPONSE']._serialized_start=7828 + _globals['_LISTPERMISSIONSRESPONSE']._serialized_end=7954 + _globals['_DELETEPERMISSIONREQUEST']._serialized_start=7956 + _globals['_DELETEPERMISSIONREQUEST']._serialized_end=8028 + _globals['_APPLYPROJECTREQUEST']._serialized_start=8030 + _globals['_APPLYPROJECTREQUEST']._serialized_end=8105 + _globals['_GETPROJECTREQUEST']._serialized_start=8107 + _globals['_GETPROJECTREQUEST']._serialized_end=8161 + _globals['_LISTPROJECTSREQUEST']._serialized_start=8164 + _globals['_LISTPROJECTSREQUEST']._serialized_end=8414 + _globals['_LISTPROJECTSREQUEST_TAGSENTRY']._serialized_start=1653 + _globals['_LISTPROJECTSREQUEST_TAGSENTRY']._serialized_end=1696 + _globals['_LISTPROJECTSRESPONSE']._serialized_start=8416 + _globals['_LISTPROJECTSRESPONSE']._serialized_end=8533 + _globals['_DELETEPROJECTREQUEST']._serialized_start=8535 + _globals['_DELETEPROJECTREQUEST']._serialized_end=8587 + _globals['_ENTITYREFERENCE']._serialized_start=8589 + _globals['_ENTITYREFERENCE']._serialized_end=8634 + _globals['_ENTITYRELATION']._serialized_start=8636 + _globals['_ENTITYRELATION']._serialized_end=8750 + _globals['_GETREGISTRYLINEAGEREQUEST']._serialized_start=8753 + _globals['_GETREGISTRYLINEAGEREQUEST']._serialized_end=8976 + _globals['_GETREGISTRYLINEAGERESPONSE']._serialized_start=8979 + _globals['_GETREGISTRYLINEAGERESPONSE']._serialized_end=9275 + _globals['_GETOBJECTRELATIONSHIPSREQUEST']._serialized_start=9278 + _globals['_GETOBJECTRELATIONSHIPSREQUEST']._serialized_end=9517 + _globals['_GETOBJECTRELATIONSHIPSRESPONSE']._serialized_start=9520 + _globals['_GETOBJECTRELATIONSHIPSRESPONSE']._serialized_end=9663 + _globals['_REGISTRYSERVER']._serialized_start=9666 + _globals['_REGISTRYSERVER']._serialized_end=14071 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.pyi b/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.pyi index 059b572fac3..ef4bdac6607 100644 --- a/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.pyi +++ b/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.pyi @@ -29,6 +29,75 @@ else: DESCRIPTOR: google.protobuf.descriptor.FileDescriptor +class PaginationParams(google.protobuf.message.Message): + """Common pagination and sorting messages""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PAGE_FIELD_NUMBER: builtins.int + LIMIT_FIELD_NUMBER: builtins.int + page: builtins.int + """1-based page number""" + limit: builtins.int + """Number of items per page""" + def __init__( + self, + *, + page: builtins.int = ..., + limit: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["limit", b"limit", "page", b"page"]) -> None: ... + +global___PaginationParams = PaginationParams + +class SortingParams(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SORT_BY_FIELD_NUMBER: builtins.int + SORT_ORDER_FIELD_NUMBER: builtins.int + sort_by: builtins.str + """Field to sort by (supports dot notation)""" + sort_order: builtins.str + """"asc" or "desc" """ + def __init__( + self, + *, + sort_by: builtins.str = ..., + sort_order: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["sort_by", b"sort_by", "sort_order", b"sort_order"]) -> None: ... + +global___SortingParams = SortingParams + +class PaginationMetadata(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PAGE_FIELD_NUMBER: builtins.int + LIMIT_FIELD_NUMBER: builtins.int + TOTAL_COUNT_FIELD_NUMBER: builtins.int + TOTAL_PAGES_FIELD_NUMBER: builtins.int + HAS_NEXT_FIELD_NUMBER: builtins.int + HAS_PREVIOUS_FIELD_NUMBER: builtins.int + page: builtins.int + limit: builtins.int + total_count: builtins.int + total_pages: builtins.int + has_next: builtins.bool + has_previous: builtins.bool + def __init__( + self, + *, + page: builtins.int = ..., + limit: builtins.int = ..., + total_count: builtins.int = ..., + total_pages: builtins.int = ..., + has_next: builtins.bool = ..., + has_previous: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["has_next", b"has_next", "has_previous", b"has_previous", "limit", b"limit", "page", b"page", "total_count", b"total_count", "total_pages", b"total_pages"]) -> None: ... + +global___PaginationMetadata = PaginationMetadata + class RefreshRequest(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -207,18 +276,27 @@ class ListEntitiesRequest(google.protobuf.message.Message): PROJECT_FIELD_NUMBER: builtins.int ALLOW_CACHE_FIELD_NUMBER: builtins.int TAGS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int project: builtins.str allow_cache: builtins.bool @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... def __init__( self, *, project: builtins.str = ..., allow_cache: builtins.bool = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "project", b"project", "tags", b"tags"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "pagination", b"pagination", "project", b"project", "sorting", b"sorting", "tags", b"tags"]) -> None: ... global___ListEntitiesRequest = ListEntitiesRequest @@ -226,14 +304,19 @@ class ListEntitiesResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor ENTITIES_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int @property def entities(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.Entity_pb2.Entity]: ... + @property + def pagination(self) -> global___PaginationMetadata: ... def __init__( self, *, entities: collections.abc.Iterable[feast.core.Entity_pb2.Entity] | None = ..., + pagination: global___PaginationMetadata | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["entities", b"entities"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["entities", b"entities", "pagination", b"pagination"]) -> None: ... global___ListEntitiesResponse = ListEntitiesResponse @@ -322,18 +405,27 @@ class ListDataSourcesRequest(google.protobuf.message.Message): PROJECT_FIELD_NUMBER: builtins.int ALLOW_CACHE_FIELD_NUMBER: builtins.int TAGS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int project: builtins.str allow_cache: builtins.bool @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... def __init__( self, *, project: builtins.str = ..., allow_cache: builtins.bool = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "project", b"project", "tags", b"tags"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "pagination", b"pagination", "project", b"project", "sorting", b"sorting", "tags", b"tags"]) -> None: ... global___ListDataSourcesRequest = ListDataSourcesRequest @@ -341,14 +433,19 @@ class ListDataSourcesResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor DATA_SOURCES_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int @property def data_sources(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.DataSource_pb2.DataSource]: ... + @property + def pagination(self) -> global___PaginationMetadata: ... def __init__( self, *, data_sources: collections.abc.Iterable[feast.core.DataSource_pb2.DataSource] | None = ..., + pagination: global___PaginationMetadata | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["data_sources", b"data_sources"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["data_sources", b"data_sources", "pagination", b"pagination"]) -> None: ... global___ListDataSourcesResponse = ListDataSourcesResponse @@ -446,18 +543,27 @@ class ListFeatureViewsRequest(google.protobuf.message.Message): PROJECT_FIELD_NUMBER: builtins.int ALLOW_CACHE_FIELD_NUMBER: builtins.int TAGS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int project: builtins.str allow_cache: builtins.bool @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... def __init__( self, *, project: builtins.str = ..., allow_cache: builtins.bool = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "project", b"project", "tags", b"tags"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "pagination", b"pagination", "project", b"project", "sorting", b"sorting", "tags", b"tags"]) -> None: ... global___ListFeatureViewsRequest = ListFeatureViewsRequest @@ -465,14 +571,19 @@ class ListFeatureViewsResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor FEATURE_VIEWS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int @property def feature_views(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.FeatureView_pb2.FeatureView]: ... + @property + def pagination(self) -> global___PaginationMetadata: ... def __init__( self, *, feature_views: collections.abc.Iterable[feast.core.FeatureView_pb2.FeatureView] | None = ..., + pagination: global___PaginationMetadata | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["feature_views", b"feature_views"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["feature_views", b"feature_views", "pagination", b"pagination"]) -> None: ... global___ListFeatureViewsResponse = ListFeatureViewsResponse @@ -578,18 +689,27 @@ class ListAllFeatureViewsRequest(google.protobuf.message.Message): PROJECT_FIELD_NUMBER: builtins.int ALLOW_CACHE_FIELD_NUMBER: builtins.int TAGS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int project: builtins.str allow_cache: builtins.bool @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... def __init__( self, *, project: builtins.str = ..., allow_cache: builtins.bool = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "project", b"project", "tags", b"tags"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "pagination", b"pagination", "project", b"project", "sorting", b"sorting", "tags", b"tags"]) -> None: ... global___ListAllFeatureViewsRequest = ListAllFeatureViewsRequest @@ -597,14 +717,19 @@ class ListAllFeatureViewsResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor FEATURE_VIEWS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int @property def feature_views(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___AnyFeatureView]: ... + @property + def pagination(self) -> global___PaginationMetadata: ... def __init__( self, *, feature_views: collections.abc.Iterable[global___AnyFeatureView] | None = ..., + pagination: global___PaginationMetadata | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["feature_views", b"feature_views"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["feature_views", b"feature_views", "pagination", b"pagination"]) -> None: ... global___ListAllFeatureViewsResponse = ListAllFeatureViewsResponse @@ -651,18 +776,27 @@ class ListStreamFeatureViewsRequest(google.protobuf.message.Message): PROJECT_FIELD_NUMBER: builtins.int ALLOW_CACHE_FIELD_NUMBER: builtins.int TAGS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int project: builtins.str allow_cache: builtins.bool @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... def __init__( self, *, project: builtins.str = ..., allow_cache: builtins.bool = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "project", b"project", "tags", b"tags"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "pagination", b"pagination", "project", b"project", "sorting", b"sorting", "tags", b"tags"]) -> None: ... global___ListStreamFeatureViewsRequest = ListStreamFeatureViewsRequest @@ -670,14 +804,19 @@ class ListStreamFeatureViewsResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor STREAM_FEATURE_VIEWS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int @property def stream_feature_views(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.StreamFeatureView_pb2.StreamFeatureView]: ... + @property + def pagination(self) -> global___PaginationMetadata: ... def __init__( self, *, stream_feature_views: collections.abc.Iterable[feast.core.StreamFeatureView_pb2.StreamFeatureView] | None = ..., + pagination: global___PaginationMetadata | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["stream_feature_views", b"stream_feature_views"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "stream_feature_views", b"stream_feature_views"]) -> None: ... global___ListStreamFeatureViewsResponse = ListStreamFeatureViewsResponse @@ -724,18 +863,27 @@ class ListOnDemandFeatureViewsRequest(google.protobuf.message.Message): PROJECT_FIELD_NUMBER: builtins.int ALLOW_CACHE_FIELD_NUMBER: builtins.int TAGS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int project: builtins.str allow_cache: builtins.bool @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... def __init__( self, *, project: builtins.str = ..., allow_cache: builtins.bool = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "project", b"project", "tags", b"tags"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "pagination", b"pagination", "project", b"project", "sorting", b"sorting", "tags", b"tags"]) -> None: ... global___ListOnDemandFeatureViewsRequest = ListOnDemandFeatureViewsRequest @@ -743,14 +891,19 @@ class ListOnDemandFeatureViewsResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor ON_DEMAND_FEATURE_VIEWS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int @property def on_demand_feature_views(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.OnDemandFeatureView_pb2.OnDemandFeatureView]: ... + @property + def pagination(self) -> global___PaginationMetadata: ... def __init__( self, *, on_demand_feature_views: collections.abc.Iterable[feast.core.OnDemandFeatureView_pb2.OnDemandFeatureView] | None = ..., + pagination: global___PaginationMetadata | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["on_demand_feature_views", b"on_demand_feature_views"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["on_demand_feature_views", b"on_demand_feature_views", "pagination", b"pagination"]) -> None: ... global___ListOnDemandFeatureViewsResponse = ListOnDemandFeatureViewsResponse @@ -819,18 +972,27 @@ class ListFeatureServicesRequest(google.protobuf.message.Message): PROJECT_FIELD_NUMBER: builtins.int ALLOW_CACHE_FIELD_NUMBER: builtins.int TAGS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int project: builtins.str allow_cache: builtins.bool @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... def __init__( self, *, project: builtins.str = ..., allow_cache: builtins.bool = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "project", b"project", "tags", b"tags"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "pagination", b"pagination", "project", b"project", "sorting", b"sorting", "tags", b"tags"]) -> None: ... global___ListFeatureServicesRequest = ListFeatureServicesRequest @@ -838,14 +1000,19 @@ class ListFeatureServicesResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor FEATURE_SERVICES_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int @property def feature_services(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.FeatureService_pb2.FeatureService]: ... + @property + def pagination(self) -> global___PaginationMetadata: ... def __init__( self, *, feature_services: collections.abc.Iterable[feast.core.FeatureService_pb2.FeatureService] | None = ..., + pagination: global___PaginationMetadata | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["feature_services", b"feature_services"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["feature_services", b"feature_services", "pagination", b"pagination"]) -> None: ... global___ListFeatureServicesResponse = ListFeatureServicesResponse @@ -934,18 +1101,27 @@ class ListSavedDatasetsRequest(google.protobuf.message.Message): PROJECT_FIELD_NUMBER: builtins.int ALLOW_CACHE_FIELD_NUMBER: builtins.int TAGS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int project: builtins.str allow_cache: builtins.bool @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... def __init__( self, *, project: builtins.str = ..., allow_cache: builtins.bool = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "project", b"project", "tags", b"tags"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "pagination", b"pagination", "project", b"project", "sorting", b"sorting", "tags", b"tags"]) -> None: ... global___ListSavedDatasetsRequest = ListSavedDatasetsRequest @@ -953,14 +1129,19 @@ class ListSavedDatasetsResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor SAVED_DATASETS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int @property def saved_datasets(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.SavedDataset_pb2.SavedDataset]: ... + @property + def pagination(self) -> global___PaginationMetadata: ... def __init__( self, *, saved_datasets: collections.abc.Iterable[feast.core.SavedDataset_pb2.SavedDataset] | None = ..., + pagination: global___PaginationMetadata | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["saved_datasets", b"saved_datasets"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "saved_datasets", b"saved_datasets"]) -> None: ... global___ListSavedDatasetsResponse = ListSavedDatasetsResponse @@ -1049,18 +1230,27 @@ class ListValidationReferencesRequest(google.protobuf.message.Message): PROJECT_FIELD_NUMBER: builtins.int ALLOW_CACHE_FIELD_NUMBER: builtins.int TAGS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int project: builtins.str allow_cache: builtins.bool @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... def __init__( self, *, project: builtins.str = ..., allow_cache: builtins.bool = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "project", b"project", "tags", b"tags"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "pagination", b"pagination", "project", b"project", "sorting", b"sorting", "tags", b"tags"]) -> None: ... global___ListValidationReferencesRequest = ListValidationReferencesRequest @@ -1068,14 +1258,19 @@ class ListValidationReferencesResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor VALIDATION_REFERENCES_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int @property def validation_references(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.ValidationProfile_pb2.ValidationReference]: ... + @property + def pagination(self) -> global___PaginationMetadata: ... def __init__( self, *, validation_references: collections.abc.Iterable[feast.core.ValidationProfile_pb2.ValidationReference] | None = ..., + pagination: global___PaginationMetadata | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["validation_references", b"validation_references"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "validation_references", b"validation_references"]) -> None: ... global___ListValidationReferencesResponse = ListValidationReferencesResponse @@ -1164,18 +1359,27 @@ class ListPermissionsRequest(google.protobuf.message.Message): PROJECT_FIELD_NUMBER: builtins.int ALLOW_CACHE_FIELD_NUMBER: builtins.int TAGS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int project: builtins.str allow_cache: builtins.bool @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... def __init__( self, *, project: builtins.str = ..., allow_cache: builtins.bool = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "project", b"project", "tags", b"tags"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "pagination", b"pagination", "project", b"project", "sorting", b"sorting", "tags", b"tags"]) -> None: ... global___ListPermissionsRequest = ListPermissionsRequest @@ -1183,14 +1387,19 @@ class ListPermissionsResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor PERMISSIONS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int @property def permissions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.Permission_pb2.Permission]: ... + @property + def pagination(self) -> global___PaginationMetadata: ... def __init__( self, *, permissions: collections.abc.Iterable[feast.core.Permission_pb2.Permission] | None = ..., + pagination: global___PaginationMetadata | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["permissions", b"permissions"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "permissions", b"permissions"]) -> None: ... global___ListPermissionsResponse = ListPermissionsResponse @@ -1272,16 +1481,25 @@ class ListProjectsRequest(google.protobuf.message.Message): ALLOW_CACHE_FIELD_NUMBER: builtins.int TAGS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int allow_cache: builtins.bool @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... def __init__( self, *, allow_cache: builtins.bool = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "tags", b"tags"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "pagination", b"pagination", "sorting", b"sorting", "tags", b"tags"]) -> None: ... global___ListProjectsRequest = ListProjectsRequest @@ -1289,14 +1507,19 @@ class ListProjectsResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor PROJECTS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int @property def projects(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.Project_pb2.Project]: ... + @property + def pagination(self) -> global___PaginationMetadata: ... def __init__( self, *, projects: collections.abc.Iterable[feast.core.Project_pb2.Project] | None = ..., + pagination: global___PaginationMetadata | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["projects", b"projects"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "projects", b"projects"]) -> None: ... global___ListProjectsResponse = ListProjectsResponse @@ -1318,7 +1541,7 @@ class DeleteProjectRequest(google.protobuf.message.Message): global___DeleteProjectRequest = DeleteProjectRequest class EntityReference(google.protobuf.message.Message): - """Lineage Messages""" + """Lineage""" DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1364,10 +1587,16 @@ class GetRegistryLineageRequest(google.protobuf.message.Message): ALLOW_CACHE_FIELD_NUMBER: builtins.int FILTER_OBJECT_TYPE_FIELD_NUMBER: builtins.int FILTER_OBJECT_NAME_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int project: builtins.str allow_cache: builtins.bool filter_object_type: builtins.str filter_object_name: builtins.str + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... def __init__( self, *, @@ -1375,8 +1604,11 @@ class GetRegistryLineageRequest(google.protobuf.message.Message): allow_cache: builtins.bool = ..., filter_object_type: builtins.str = ..., filter_object_name: builtins.str = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "filter_object_name", b"filter_object_name", "filter_object_type", b"filter_object_type", "project", b"project"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "filter_object_name", b"filter_object_name", "filter_object_type", b"filter_object_type", "pagination", b"pagination", "project", b"project", "sorting", b"sorting"]) -> None: ... global___GetRegistryLineageRequest = GetRegistryLineageRequest @@ -1385,17 +1617,26 @@ class GetRegistryLineageResponse(google.protobuf.message.Message): RELATIONSHIPS_FIELD_NUMBER: builtins.int INDIRECT_RELATIONSHIPS_FIELD_NUMBER: builtins.int + RELATIONSHIPS_PAGINATION_FIELD_NUMBER: builtins.int + INDIRECT_RELATIONSHIPS_PAGINATION_FIELD_NUMBER: builtins.int @property def relationships(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___EntityRelation]: ... @property def indirect_relationships(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___EntityRelation]: ... + @property + def relationships_pagination(self) -> global___PaginationMetadata: ... + @property + def indirect_relationships_pagination(self) -> global___PaginationMetadata: ... def __init__( self, *, relationships: collections.abc.Iterable[global___EntityRelation] | None = ..., indirect_relationships: collections.abc.Iterable[global___EntityRelation] | None = ..., + relationships_pagination: global___PaginationMetadata | None = ..., + indirect_relationships_pagination: global___PaginationMetadata | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["indirect_relationships", b"indirect_relationships", "relationships", b"relationships"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["indirect_relationships_pagination", b"indirect_relationships_pagination", "relationships_pagination", b"relationships_pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["indirect_relationships", b"indirect_relationships", "indirect_relationships_pagination", b"indirect_relationships_pagination", "relationships", b"relationships", "relationships_pagination", b"relationships_pagination"]) -> None: ... global___GetRegistryLineageResponse = GetRegistryLineageResponse @@ -1407,11 +1648,17 @@ class GetObjectRelationshipsRequest(google.protobuf.message.Message): OBJECT_NAME_FIELD_NUMBER: builtins.int INCLUDE_INDIRECT_FIELD_NUMBER: builtins.int ALLOW_CACHE_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int project: builtins.str object_type: builtins.str object_name: builtins.str include_indirect: builtins.bool allow_cache: builtins.bool + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... def __init__( self, *, @@ -1420,8 +1667,11 @@ class GetObjectRelationshipsRequest(google.protobuf.message.Message): object_name: builtins.str = ..., include_indirect: builtins.bool = ..., allow_cache: builtins.bool = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "include_indirect", b"include_indirect", "object_name", b"object_name", "object_type", b"object_type", "project", b"project"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "include_indirect", b"include_indirect", "object_name", b"object_name", "object_type", b"object_type", "pagination", b"pagination", "project", b"project", "sorting", b"sorting"]) -> None: ... global___GetObjectRelationshipsRequest = GetObjectRelationshipsRequest @@ -1429,13 +1679,18 @@ class GetObjectRelationshipsResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor RELATIONSHIPS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int @property def relationships(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___EntityRelation]: ... + @property + def pagination(self) -> global___PaginationMetadata: ... def __init__( self, *, relationships: collections.abc.Iterable[global___EntityRelation] | None = ..., + pagination: global___PaginationMetadata | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["relationships", b"relationships"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "relationships", b"relationships"]) -> None: ... global___GetObjectRelationshipsResponse = GetObjectRelationshipsResponse diff --git a/sdk/python/feast/registry_server.py b/sdk/python/feast/registry_server.py index 5d5f4281149..56c3eb5a37d 100644 --- a/sdk/python/feast/registry_server.py +++ b/sdk/python/feast/registry_server.py @@ -1,7 +1,7 @@ import logging from concurrent import futures from datetime import datetime, timezone -from typing import Optional, Union, cast +from typing import Any, List, Optional, Union, cast import grpc from google.protobuf.empty_pb2 import Empty @@ -43,6 +43,107 @@ logger.setLevel(logging.INFO) +def apply_pagination_and_sorting( + objects: List[Any], + pagination: Optional[RegistryServer_pb2.PaginationParams] = None, + sorting: Optional[RegistryServer_pb2.SortingParams] = None, +) -> tuple[List[Any], RegistryServer_pb2.PaginationMetadata]: + """ + Apply sorting and pagination to a list of objects at the gRPC layer. + + Args: + objects: List of objects to paginate and sort + pagination: Pagination parameters (page, limit) + sorting: Sorting parameters (sort_by, sort_order) + + Returns: + Tuple of (paginated and sorted objects, pagination metadata) + """ + if not objects: + empty_metadata = RegistryServer_pb2.PaginationMetadata( + page=0, + limit=0, + total_count=0, + total_pages=0, + has_next=False, + has_previous=False, + ) + return objects, empty_metadata + + if sorting and sorting.sort_by and sorting.sort_by.strip(): + objects = apply_sorting(objects, sorting.sort_by, sorting.sort_order) + + total_count = len(objects) + + # Apply pagination if requested + if pagination and pagination.page > 0 and pagination.limit > 0: + start_idx = (pagination.page - 1) * pagination.limit + end_idx = start_idx + pagination.limit + paginated_objects = objects[start_idx:end_idx] + + total_pages = (total_count + pagination.limit - 1) // pagination.limit + has_next = pagination.page < total_pages + has_previous = pagination.page > 1 + + pagination_metadata = RegistryServer_pb2.PaginationMetadata( + page=pagination.page, + limit=pagination.limit, + total_count=total_count, + total_pages=total_pages, + has_next=has_next, + has_previous=has_previous, + ) + return paginated_objects, pagination_metadata + else: + # No pagination requested - return all objects + pagination_metadata = RegistryServer_pb2.PaginationMetadata( + page=0, + limit=0, + total_count=total_count, + total_pages=1, + has_next=False, + has_previous=False, + ) + return objects, pagination_metadata + + +def apply_sorting(objects: List[Any], sort_by: str, sort_order: str) -> List[Any]: + """Apply sorting to a list of objects using dot notation for nested attributes.""" + + def get_nested_attr(obj, attr_path: str): + """Get nested attribute using dot notation.""" + attrs = attr_path.split(".") + current = obj + for attr in attrs: + if hasattr(current, attr): + current = getattr(current, attr) + elif isinstance(current, dict) and attr in current: + current = current[attr] + else: + return None + return current + + def sort_key(obj): + value = get_nested_attr(obj, sort_by) + if value is None: + return ("", 0, None) + + if isinstance(value, str): + return (value.lower(), 1, None) + elif isinstance(value, (int, float)): + return ("", 1, value) + else: + return (str(value).lower(), 1, None) + + reverse = sort_order.lower() == "desc" + + try: + return sorted(objects, key=sort_key, reverse=reverse) + except Exception as e: + logger.warning(f"Failed to sort objects by '{sort_by}': {e}") + return objects + + def _build_any_feature_view_proto(feature_view: BaseFeatureView): if isinstance(feature_view, StreamFeatureView): arg_name = "stream_feature_view" @@ -98,21 +199,25 @@ def GetEntity(self, request: RegistryServer_pb2.GetEntityRequest, context): ).to_proto() def ListEntities(self, request: RegistryServer_pb2.ListEntitiesRequest, context): - return RegistryServer_pb2.ListEntitiesResponse( - entities=[ - entity.to_proto() - for entity in permitted_resources( - resources=cast( - list[FeastObject], - self.proxied_registry.list_entities( - project=request.project, - allow_cache=request.allow_cache, - tags=dict(request.tags), - ), + paginated_entities, pagination_metadata = apply_pagination_and_sorting( + permitted_resources( + resources=cast( + list[FeastObject], + self.proxied_registry.list_entities( + project=request.project, + allow_cache=request.allow_cache, + tags=dict(request.tags), ), - actions=AuthzedAction.DESCRIBE, - ) - ] + ), + actions=AuthzedAction.DESCRIBE, + ), + pagination=request.pagination, + sorting=request.sorting, + ) + + return RegistryServer_pb2.ListEntitiesResponse( + entities=[entity.to_proto() for entity in paginated_entities], + pagination=pagination_metadata, ) def DeleteEntity(self, request: RegistryServer_pb2.DeleteEntityRequest, context): @@ -160,21 +265,27 @@ def GetDataSource(self, request: RegistryServer_pb2.GetDataSourceRequest, contex def ListDataSources( self, request: RegistryServer_pb2.ListDataSourcesRequest, context ): + paginated_data_sources, pagination_metadata = apply_pagination_and_sorting( + permitted_resources( + resources=cast( + list[FeastObject], + self.proxied_registry.list_data_sources( + project=request.project, + allow_cache=request.allow_cache, + tags=dict(request.tags), + ), + ), + actions=AuthzedAction.DESCRIBE, + ), + pagination=request.pagination, + sorting=request.sorting, + ) + return RegistryServer_pb2.ListDataSourcesResponse( data_sources=[ - data_source.to_proto() - for data_source in permitted_resources( - resources=cast( - list[FeastObject], - self.proxied_registry.list_data_sources( - project=request.project, - allow_cache=request.allow_cache, - tags=dict(request.tags), - ), - ), - actions=AuthzedAction.DESCRIBE, - ) - ] + data_source.to_proto() for data_source in paginated_data_sources + ], + pagination=pagination_metadata, ) def DeleteDataSource( @@ -259,41 +370,54 @@ def ApplyFeatureView( def ListFeatureViews( self, request: RegistryServer_pb2.ListFeatureViewsRequest, context ): + paginated_feature_views, pagination_metadata = apply_pagination_and_sorting( + permitted_resources( + resources=cast( + list[FeastObject], + self.proxied_registry.list_feature_views( + project=request.project, + allow_cache=request.allow_cache, + tags=dict(request.tags), + ), + ), + actions=AuthzedAction.DESCRIBE, + ), + pagination=request.pagination, + sorting=request.sorting, + ) + return RegistryServer_pb2.ListFeatureViewsResponse( feature_views=[ - feature_view.to_proto() - for feature_view in permitted_resources( - resources=cast( - list[FeastObject], - self.proxied_registry.list_feature_views( - project=request.project, - allow_cache=request.allow_cache, - tags=dict(request.tags), - ), - ), - actions=AuthzedAction.DESCRIBE, - ) - ] + feature_view.to_proto() for feature_view in paginated_feature_views + ], + pagination=pagination_metadata, ) def ListAllFeatureViews( self, request: RegistryServer_pb2.ListAllFeatureViewsRequest, context ): + paginated_feature_views, pagination_metadata = apply_pagination_and_sorting( + permitted_resources( + resources=cast( + list[FeastObject], + self.proxied_registry.list_all_feature_views( + project=request.project, + allow_cache=request.allow_cache, + tags=dict(request.tags), + ), + ), + actions=AuthzedAction.DESCRIBE, + ), + pagination=request.pagination, + sorting=request.sorting, + ) + return RegistryServer_pb2.ListAllFeatureViewsResponse( feature_views=[ _build_any_feature_view_proto(cast(BaseFeatureView, feature_view)) - for feature_view in permitted_resources( - resources=cast( - list[FeastObject], - self.proxied_registry.list_all_feature_views( - project=request.project, - allow_cache=request.allow_cache, - tags=dict(request.tags), - ), - ), - actions=AuthzedAction.DESCRIBE, - ) - ] + for feature_view in paginated_feature_views + ], + pagination=pagination_metadata, ) def DeleteFeatureView( @@ -334,10 +458,9 @@ def GetStreamFeatureView( def ListStreamFeatureViews( self, request: RegistryServer_pb2.ListStreamFeatureViewsRequest, context ): - return RegistryServer_pb2.ListStreamFeatureViewsResponse( - stream_feature_views=[ - stream_feature_view.to_proto() - for stream_feature_view in permitted_resources( + paginated_stream_feature_views, pagination_metadata = ( + apply_pagination_and_sorting( + permitted_resources( resources=cast( list[FeastObject], self.proxied_registry.list_stream_feature_views( @@ -347,8 +470,18 @@ def ListStreamFeatureViews( ), ), actions=AuthzedAction.DESCRIBE, - ) - ] + ), + pagination=request.pagination, + sorting=request.sorting, + ) + ) + + return RegistryServer_pb2.ListStreamFeatureViewsResponse( + stream_feature_views=[ + stream_feature_view.to_proto() + for stream_feature_view in paginated_stream_feature_views + ], + pagination=pagination_metadata, ) def GetOnDemandFeatureView( @@ -366,10 +499,9 @@ def GetOnDemandFeatureView( def ListOnDemandFeatureViews( self, request: RegistryServer_pb2.ListOnDemandFeatureViewsRequest, context ): - return RegistryServer_pb2.ListOnDemandFeatureViewsResponse( - on_demand_feature_views=[ - on_demand_feature_view.to_proto() - for on_demand_feature_view in permitted_resources( + paginated_on_demand_feature_views, pagination_metadata = ( + apply_pagination_and_sorting( + permitted_resources( resources=cast( list[FeastObject], self.proxied_registry.list_on_demand_feature_views( @@ -379,8 +511,18 @@ def ListOnDemandFeatureViews( ), ), actions=AuthzedAction.DESCRIBE, - ) - ] + ), + pagination=request.pagination, + sorting=request.sorting, + ) + ) + + return RegistryServer_pb2.ListOnDemandFeatureViewsResponse( + on_demand_feature_views=[ + on_demand_feature_view.to_proto() + for on_demand_feature_view in paginated_on_demand_feature_views + ], + pagination=pagination_metadata, ) def ApplyFeatureService( @@ -417,35 +559,40 @@ def GetFeatureService( def ListFeatureServices( self, request: RegistryServer_pb2.ListFeatureServicesRequest, context ): + paginated_feature_services, pagination_metadata = apply_pagination_and_sorting( + permitted_resources( + resources=cast( + list[FeastObject], + self.proxied_registry.list_feature_services( + project=request.project, + allow_cache=request.allow_cache, + tags=dict(request.tags), + ), + ), + actions=AuthzedAction.DESCRIBE, + ), + pagination=request.pagination, + sorting=request.sorting, + ) + return RegistryServer_pb2.ListFeatureServicesResponse( feature_services=[ feature_service.to_proto() - for feature_service in permitted_resources( - resources=cast( - list[FeastObject], - self.proxied_registry.list_feature_services( - project=request.project, - allow_cache=request.allow_cache, - tags=dict(request.tags), - ), - ), - actions=AuthzedAction.DESCRIBE, - ) - ] + for feature_service in paginated_feature_services + ], + pagination=pagination_metadata, ) def DeleteFeatureService( self, request: RegistryServer_pb2.DeleteFeatureServiceRequest, context ): - ( - assert_permissions( - resource=self.proxied_registry.get_feature_service( - name=request.name, project=request.project - ), - actions=[AuthzedAction.DELETE], - ), + feature_service = self.proxied_registry.get_feature_service( + name=request.name, project=request.project, allow_cache=False + ) + assert_permissions( + resource=feature_service, + actions=[AuthzedAction.DELETE], ) - self.proxied_registry.delete_feature_service( name=request.name, project=request.project, commit=request.commit ) @@ -485,36 +632,43 @@ def GetSavedDataset( def ListSavedDatasets( self, request: RegistryServer_pb2.ListSavedDatasetsRequest, context ): + paginated_saved_datasets, pagination_metadata = apply_pagination_and_sorting( + permitted_resources( + resources=cast( + list[FeastObject], + self.proxied_registry.list_saved_datasets( + project=request.project, + allow_cache=request.allow_cache, + tags=dict(request.tags), + ), + ), + actions=AuthzedAction.DESCRIBE, + ), + pagination=request.pagination, + sorting=request.sorting, + ) + return RegistryServer_pb2.ListSavedDatasetsResponse( saved_datasets=[ - saved_dataset.to_proto() - for saved_dataset in permitted_resources( - resources=cast( - list[FeastObject], - self.proxied_registry.list_saved_datasets( - project=request.project, - allow_cache=request.allow_cache, - tags=dict(request.tags), - ), - ), - actions=AuthzedAction.DESCRIBE, - ) - ] + saved_dataset.to_proto() for saved_dataset in paginated_saved_datasets + ], + pagination=pagination_metadata, ) def DeleteSavedDataset( self, request: RegistryServer_pb2.DeleteSavedDatasetRequest, context ): + saved_dataset = self.proxied_registry.get_saved_dataset( + name=request.name, project=request.project, allow_cache=False + ) assert_permissions( - resource=self.proxied_registry.get_saved_dataset( - name=request.name, project=request.project - ), + resource=saved_dataset, actions=[AuthzedAction.DELETE], ) - self.proxied_registry.delete_saved_dataset( name=request.name, project=request.project, commit=request.commit ) + return Empty() def ApplyValidationReference( @@ -551,10 +705,9 @@ def GetValidationReference( def ListValidationReferences( self, request: RegistryServer_pb2.ListValidationReferencesRequest, context ): - return RegistryServer_pb2.ListValidationReferencesResponse( - validation_references=[ - validation_reference.to_proto() - for validation_reference in permitted_resources( + paginated_validation_references, pagination_metadata = ( + apply_pagination_and_sorting( + permitted_resources( resources=cast( list[FeastObject], self.proxied_registry.list_validation_references( @@ -564,17 +717,28 @@ def ListValidationReferences( ), ), actions=AuthzedAction.DESCRIBE, - ) - ] + ), + pagination=request.pagination, + sorting=request.sorting, + ) + ) + + return RegistryServer_pb2.ListValidationReferencesResponse( + validation_references=[ + validation_reference.to_proto() + for validation_reference in paginated_validation_references + ], + pagination=pagination_metadata, ) def DeleteValidationReference( self, request: RegistryServer_pb2.DeleteValidationReferenceRequest, context ): + validation_reference = self.proxied_registry.get_validation_reference( + name=request.name, project=request.project, allow_cache=False + ) assert_permissions( - resource=self.proxied_registry.get_validation_reference( - name=request.name, project=request.project - ), + resource=validation_reference, actions=[AuthzedAction.DELETE], ) self.proxied_registry.delete_validation_reference( @@ -648,49 +812,53 @@ def ApplyPermission( return Empty() def GetPermission(self, request: RegistryServer_pb2.GetPermissionRequest, context): - permission = self.proxied_registry.get_permission( - name=request.name, project=request.project, allow_cache=request.allow_cache - ) - assert_permissions( - resource=permission, + return assert_permissions( + self.proxied_registry.get_permission( + name=request.name, + project=request.project, + allow_cache=request.allow_cache, + ), actions=[AuthzedAction.DESCRIBE], - ) - permission.to_proto().spec.project = request.project - - return permission.to_proto() + ).to_proto() def ListPermissions( self, request: RegistryServer_pb2.ListPermissionsRequest, context ): - return RegistryServer_pb2.ListPermissionsResponse( - permissions=[ - permission.to_proto() - for permission in permitted_resources( - resources=cast( - list[FeastObject], - self.proxied_registry.list_permissions( - project=request.project, allow_cache=request.allow_cache - ), + paginated_permissions, pagination_metadata = apply_pagination_and_sorting( + permitted_resources( + resources=cast( + list[FeastObject], + self.proxied_registry.list_permissions( + project=request.project, + allow_cache=request.allow_cache, + tags=dict(request.tags), ), - actions=AuthzedAction.DESCRIBE, - ) - ] + ), + actions=AuthzedAction.DESCRIBE, + ), + pagination=request.pagination, + sorting=request.sorting, + ) + + return RegistryServer_pb2.ListPermissionsResponse( + permissions=[permission.to_proto() for permission in paginated_permissions], + pagination=pagination_metadata, ) def DeletePermission( self, request: RegistryServer_pb2.DeletePermissionRequest, context ): + permission = self.proxied_registry.get_permission( + name=request.name, project=request.project, allow_cache=False + ) assert_permissions( - resource=self.proxied_registry.get_permission( - name=request.name, - project=request.project, - ), + resource=permission, actions=[AuthzedAction.DELETE], ) - self.proxied_registry.delete_permission( name=request.name, project=request.project, commit=request.commit ) + return Empty() def ApplyProject(self, request: RegistryServer_pb2.ApplyProjectRequest, context): @@ -709,62 +877,82 @@ def ApplyProject(self, request: RegistryServer_pb2.ApplyProjectRequest, context) return Empty() def GetProject(self, request: RegistryServer_pb2.GetProjectRequest, context): - project = self.proxied_registry.get_project( - name=request.name, allow_cache=request.allow_cache - ) - assert_permissions( - resource=project, + return assert_permissions( + self.proxied_registry.get_project( + name=request.name, + allow_cache=request.allow_cache, + ), actions=[AuthzedAction.DESCRIBE], - ) - return project.to_proto() + ).to_proto() def ListProjects(self, request: RegistryServer_pb2.ListProjectsRequest, context): - return RegistryServer_pb2.ListProjectsResponse( - projects=[ - project.to_proto() - for project in permitted_resources( - resources=cast( - list[FeastObject], - self.proxied_registry.list_projects( - allow_cache=request.allow_cache - ), + paginated_projects, pagination_metadata = apply_pagination_and_sorting( + permitted_resources( + resources=cast( + list[FeastObject], + self.proxied_registry.list_projects( + allow_cache=request.allow_cache, + tags=dict(request.tags), ), - actions=AuthzedAction.DESCRIBE, - ) - ] + ), + actions=AuthzedAction.DESCRIBE, + ), + pagination=request.pagination, + sorting=request.sorting, + ) + + return RegistryServer_pb2.ListProjectsResponse( + projects=[project.to_proto() for project in paginated_projects], + pagination=pagination_metadata, ) def DeleteProject(self, request: RegistryServer_pb2.DeleteProjectRequest, context): + project = self.proxied_registry.get_project( + name=request.name, allow_cache=False + ) assert_permissions( - resource=self.proxied_registry.get_project( - name=request.name, - ), + resource=project, actions=[AuthzedAction.DELETE], ) - self.proxied_registry.delete_project(name=request.name, commit=request.commit) + return Empty() def GetRegistryLineage( self, request: RegistryServer_pb2.GetRegistryLineageRequest, context ): - """Get complete registry lineage with relationships and indirect relationships.""" - relationships, indirect_relationships = ( + direct_relationships, indirect_relationships = ( self.proxied_registry.get_registry_lineage( project=request.project, allow_cache=request.allow_cache, - filter_object_type=request.filter_object_type - if request.filter_object_type - else None, - filter_object_name=request.filter_object_name - if request.filter_object_name - else None, + filter_object_type=request.filter_object_type, + filter_object_name=request.filter_object_name, + ) + ) + + paginated_relationships, relationships_pagination = ( + apply_pagination_and_sorting( + direct_relationships, + pagination=request.pagination, + sorting=request.sorting, + ) + ) + + paginated_indirect_relationships, indirect_relationships_pagination = ( + apply_pagination_and_sorting( + indirect_relationships, + pagination=request.pagination, + sorting=request.sorting, ) ) return RegistryServer_pb2.GetRegistryLineageResponse( - relationships=[rel.to_proto() for rel in relationships], - indirect_relationships=[rel.to_proto() for rel in indirect_relationships], + relationships=[rel.to_proto() for rel in paginated_relationships], + indirect_relationships=[ + rel.to_proto() for rel in paginated_indirect_relationships + ], + relationships_pagination=relationships_pagination, + indirect_relationships_pagination=indirect_relationships_pagination, ) def GetObjectRelationships( @@ -779,8 +967,15 @@ def GetObjectRelationships( allow_cache=request.allow_cache, ) + paginated_relationships, pagination_metadata = apply_pagination_and_sorting( + relationships, + pagination=request.pagination, + sorting=request.sorting, + ) + return RegistryServer_pb2.GetObjectRelationshipsResponse( - relationships=[rel.to_proto() for rel in relationships] + relationships=[rel.to_proto() for rel in paginated_relationships], + pagination=pagination_metadata, ) def Commit(self, request, context): diff --git a/sdk/python/tests/unit/api/test_api_rest_registry.py b/sdk/python/tests/unit/api/test_api_rest_registry.py index 5cc693fd4b9..5cb8a4bf187 100644 --- a/sdk/python/tests/unit/api/test_api_rest_registry.py +++ b/sdk/python/tests/unit/api/test_api_rest_registry.py @@ -327,3 +327,494 @@ def test_saved_datasets_via_rest(fastapi_test_app): assert ( response.status_code == 422 ) # Unprocessable Entity for missing required query param + + +@pytest.fixture +def fastapi_test_app_with_multiple_objects(): + """Test app with multiple objects for pagination and sorting tests.""" + tmp_dir = tempfile.TemporaryDirectory() + registry_path = os.path.join(tmp_dir.name, "registry.db") + + parquet_file_path = os.path.join(tmp_dir.name, "data.parquet") + import pandas as pd + + df = pd.DataFrame( + { + "user_id": [1, 2, 3], + "age": [25, 30, 22], + "income": [50000.0, 60000.0, 45000.0], + "event_timestamp": pd.to_datetime( + ["2024-01-01", "2024-01-02", "2024-01-03"] + ), + } + ) + df.to_parquet(parquet_file_path) + config = { + "registry": registry_path, + "project": "demo_project", + "provider": "local", + "offline_store": {"type": "file"}, + "online_store": {"type": "sqlite", "path": ":memory:"}, + } + + store = FeatureStore(config=RepoConfig.model_validate(config)) + + # Create multiple entities for testing + entities = [ + Entity(name="user_id", value_type=ValueType.INT64, description="User ID"), + Entity( + name="customer_id", value_type=ValueType.INT64, description="Customer ID" + ), + Entity(name="product_id", value_type=ValueType.INT64, description="Product ID"), + Entity(name="order_id", value_type=ValueType.INT64, description="Order ID"), + Entity(name="session_id", value_type=ValueType.INT64, description="Session ID"), + ] + + data_sources = [ + FileSource( + name="user_profile_source", + path=parquet_file_path, + event_timestamp_column="event_timestamp", + ), + FileSource( + name="customer_data_source", + path=parquet_file_path, + event_timestamp_column="event_timestamp", + ), + FileSource( + name="product_catalog_source", + path=parquet_file_path, + event_timestamp_column="event_timestamp", + ), + ] + + feature_views = [ + FeatureView( + name="user_profile", + entities=[entities[0]], + ttl=None, + schema=[ + Field(name="age", dtype=Int64), + Field(name="income", dtype=Float64), + ], + source=data_sources[0], + ), + FeatureView( + name="customer_features", + entities=[entities[1]], + ttl=None, + schema=[ + Field(name="age", dtype=Int64), + ], + source=data_sources[1], + ), + FeatureView( + name="product_features", + entities=[entities[2]], + ttl=None, + schema=[ + Field(name="income", dtype=Float64), + ], + source=data_sources[2], + ), + ] + + feature_services = [ + FeatureService( + name="user_service", + features=[feature_views[0]], + ), + FeatureService( + name="customer_service", + features=[feature_views[1]], + ), + FeatureService( + name="analytics_service", + features=[feature_views[0], feature_views[1]], + ), + ] + + saved_datasets = [ + SavedDataset( + name="dataset_alpha", + features=["user_profile:age"], + join_keys=["user_id"], + storage=SavedDatasetFileStorage(path=parquet_file_path), + tags={"environment": "test", "version": "1.0"}, + ), + SavedDataset( + name="dataset_beta", + features=["user_profile:income"], + join_keys=["user_id"], + storage=SavedDatasetFileStorage(path=parquet_file_path), + tags={"environment": "prod", "version": "2.0"}, + ), + SavedDataset( + name="dataset_gamma", + features=["customer_features:age"], + join_keys=["customer_id"], + storage=SavedDatasetFileStorage(path=parquet_file_path), + tags={"environment": "test", "version": "1.5"}, + ), + ] + store.apply(entities + data_sources + feature_views + feature_services) + + for dataset in saved_datasets: + store._registry.apply_saved_dataset(dataset, "demo_project") + + rest_server = RestRegistryServer(store) + client = TestClient(rest_server.app) + + yield client + + tmp_dir.cleanup() + + +def test_entities_pagination_via_rest(fastapi_test_app_with_multiple_objects): + """Test pagination for entities endpoint.""" + client = fastapi_test_app_with_multiple_objects + + # Test basic pagination - first page + response = client.get("/entities?project=demo_project&page=1&limit=2") + assert response.status_code == 200 + data = response.json() + assert "entities" in data + assert "pagination" in data + assert len(data["entities"]) == 2 + assert data["pagination"]["page"] == 1 + assert data["pagination"]["limit"] == 2 + assert data["pagination"]["totalCount"] == 6 + assert data["pagination"]["totalPages"] == 3 + assert data["pagination"]["hasNext"] is True + + # Test pagination - second page + response = client.get("/entities?project=demo_project&page=2&limit=2") + assert response.status_code == 200 + data = response.json() + assert len(data["entities"]) == 2 + assert data["pagination"]["page"] == 2 + assert data["pagination"]["hasNext"] is True + + # Test pagination - last page + response = client.get("/entities?project=demo_project&page=3&limit=2") + assert response.status_code == 200 + data = response.json() + # Page 3 might be beyond available pages + assert data["pagination"]["page"] == 3 + + # Test pagination beyond available pages + response = client.get("/entities?project=demo_project&page=5&limit=2") + assert response.status_code == 200 + data = response.json() + # Beyond available pages should not include entities key + assert "entities" not in data or len(data["entities"]) == 0 + assert data["pagination"]["page"] == 5 + + +def test_entities_sorting_via_rest(fastapi_test_app_with_multiple_objects): + """Test sorting for entities endpoint.""" + client = fastapi_test_app_with_multiple_objects + + # Test sorting by name ascending + response = client.get("/entities?project=demo_project&sort_by=name&sort_order=asc") + assert response.status_code == 200 + data = response.json() + entity_names = [entity["spec"]["name"] for entity in data["entities"]] + assert entity_names == sorted(entity_names) + + # Test sorting by name descending + response = client.get("/entities?project=demo_project&sort_by=name&sort_order=desc") + assert response.status_code == 200 + data = response.json() + entity_names = [entity["spec"]["name"] for entity in data["entities"]] + assert entity_names == sorted(entity_names, reverse=True) + + +def test_entities_pagination_with_sorting_via_rest( + fastapi_test_app_with_multiple_objects, +): + """Test combined pagination and sorting for entities endpoint.""" + client = fastapi_test_app_with_multiple_objects + + # Test pagination with sorting + response = client.get( + "/entities?project=demo_project&page=1&limit=2&sort_by=name&sort_order=asc" + ) + assert response.status_code == 200 + data = response.json() + assert len(data["entities"]) == 2 + entity_names = [entity["spec"]["name"] for entity in data["entities"]] + assert entity_names == sorted(entity_names) + assert data["pagination"]["page"] == 1 + assert data["pagination"]["limit"] == 2 + assert data["pagination"]["totalCount"] == 6 + + +def test_feature_views_pagination_via_rest(fastapi_test_app_with_multiple_objects): + """Test pagination for feature views endpoint.""" + client = fastapi_test_app_with_multiple_objects + + response = client.get("/feature_views?project=demo_project&page=1&limit=2") + assert response.status_code == 200 + data = response.json() + assert "featureViews" in data + assert "pagination" in data + assert len(data["featureViews"]) == 2 + assert data["pagination"]["page"] == 1 + assert data["pagination"]["limit"] == 2 + assert data["pagination"]["totalCount"] == 3 + assert data["pagination"]["totalPages"] == 2 + assert data["pagination"]["hasNext"] is True + + +def test_feature_views_sorting_via_rest(fastapi_test_app_with_multiple_objects): + """Test sorting for feature views endpoint.""" + client = fastapi_test_app_with_multiple_objects + + # Test sorting by name ascending + response = client.get( + "/feature_views?project=demo_project&sort_by=name&sort_order=asc" + ) + assert response.status_code == 200 + data = response.json() + fv_names = [fv["featureView"]["spec"]["name"] for fv in data["featureViews"]] + assert fv_names == sorted(fv_names) + + # Test sorting by name descending + response = client.get( + "/feature_views?project=demo_project&sort_by=name&sort_order=desc" + ) + assert response.status_code == 200 + data = response.json() + fv_names = [fv["featureView"]["spec"]["name"] for fv in data["featureViews"]] + assert fv_names == sorted(fv_names, reverse=True) + + +def test_feature_services_pagination_via_rest(fastapi_test_app_with_multiple_objects): + """Test pagination for feature services endpoint.""" + client = fastapi_test_app_with_multiple_objects + + # Test basic pagination + response = client.get("/feature_services?project=demo_project&page=1&limit=2") + assert response.status_code == 200 + data = response.json() + assert "featureServices" in data + assert "pagination" in data + assert len(data["featureServices"]) == 2 + assert data["pagination"]["page"] == 1 + assert data["pagination"]["limit"] == 2 + assert data["pagination"]["totalCount"] == 3 + assert data["pagination"]["totalPages"] == 2 + + +def test_feature_services_sorting_via_rest(fastapi_test_app_with_multiple_objects): + """Test sorting for feature services endpoint.""" + client = fastapi_test_app_with_multiple_objects + + # Test sorting by name ascending + response = client.get( + "/feature_services?project=demo_project&sort_by=name&sort_order=asc" + ) + assert response.status_code == 200 + data = response.json() + fs_names = [fs["spec"]["name"] for fs in data["featureServices"]] + assert fs_names == sorted(fs_names) + + +def test_data_sources_pagination_via_rest(fastapi_test_app_with_multiple_objects): + """Test pagination for data sources endpoint.""" + client = fastapi_test_app_with_multiple_objects + + # Test basic pagination + response = client.get("/data_sources?project=demo_project&page=1&limit=2") + assert response.status_code == 200 + data = response.json() + assert "data_sources" in data + assert "pagination" in data + assert len(data["data_sources"]) == 2 + assert data["pagination"]["page"] == 1 + assert data["pagination"]["limit"] == 2 + assert data["pagination"]["totalCount"] == 3 + assert data["pagination"]["totalPages"] == 2 + + +def test_data_sources_sorting_via_rest(fastapi_test_app_with_multiple_objects): + """Test sorting for data sources endpoint.""" + client = fastapi_test_app_with_multiple_objects + + # Test sorting by name ascending + response = client.get( + "/data_sources?project=demo_project&sort_by=name&sort_order=asc" + ) + assert response.status_code == 200 + data = response.json() + ds_names = [ds["name"] for ds in data["data_sources"]] + assert ds_names == sorted(ds_names) + + +def test_saved_datasets_pagination_via_rest(fastapi_test_app_with_multiple_objects): + """Test pagination for saved datasets endpoint.""" + client = fastapi_test_app_with_multiple_objects + + # Test basic pagination + response = client.get("/saved_datasets?project=demo_project&page=1&limit=2") + assert response.status_code == 200 + data = response.json() + assert "saved_datasets" in data + assert "pagination" in data + assert len(data["saved_datasets"]) == 2 + assert data["pagination"]["page"] == 1 + assert data["pagination"]["limit"] == 2 + assert data["pagination"]["totalCount"] == 3 + assert data["pagination"]["totalPages"] == 2 + + +def test_saved_datasets_sorting_via_rest(fastapi_test_app_with_multiple_objects): + """Test sorting for saved datasets endpoint.""" + client = fastapi_test_app_with_multiple_objects + + # Test sorting by name ascending + response = client.get( + "/saved_datasets?project=demo_project&sort_by=name&sort_order=asc" + ) + assert response.status_code == 200 + data = response.json() + sd_names = [sd["spec"]["name"] for sd in data["saved_datasets"]] + assert sd_names == sorted(sd_names) + + # Test sorting by name descending + response = client.get( + "/saved_datasets?project=demo_project&sort_by=name&sort_order=desc" + ) + assert response.status_code == 200 + data = response.json() + sd_names = [sd["spec"]["name"] for sd in data["saved_datasets"]] + assert sd_names == sorted(sd_names, reverse=True) + + +def test_projects_pagination_via_rest(fastapi_test_app_with_multiple_objects): + """Test pagination for projects endpoint.""" + client = fastapi_test_app_with_multiple_objects + + # Test basic pagination + response = client.get("/projects?page=1&limit=2") + assert response.status_code == 200 + data = response.json() + assert "projects" in data + assert "pagination" in data + # Should have at least 1 project (demo_project) + assert len(data["projects"]) >= 1 + assert data["pagination"]["page"] == 1 + assert data["pagination"]["limit"] == 2 + + +def test_projects_sorting_via_rest(fastapi_test_app_with_multiple_objects): + """Test sorting for projects endpoint.""" + client = fastapi_test_app_with_multiple_objects + + # Test sorting by name ascending + response = client.get("/projects?sort_by=name&sort_order=asc") + assert response.status_code == 200 + data = response.json() + project_names = [project["spec"]["name"] for project in data["projects"]] + assert project_names == sorted(project_names) + + +def test_pagination_invalid_parameters_via_rest(fastapi_test_app_with_multiple_objects): + """Test pagination with invalid parameters.""" + client = fastapi_test_app_with_multiple_objects + + # Test invalid page number (negative) + response = client.get("/entities?project=demo_project&page=-1&limit=2") + assert response.status_code == 422 # Validation error + + # Test invalid limit (negative) + response = client.get("/entities?project=demo_project&page=1&limit=-1") + assert response.status_code == 422 # Validation error + + # Test invalid limit (too large) + response = client.get("/entities?project=demo_project&page=1&limit=1000") + assert response.status_code == 422 # Validation error + + # Test invalid page number (zero) + response = client.get("/entities?project=demo_project&page=0&limit=2") + assert response.status_code == 422 # Validation error + + +def test_sorting_invalid_parameters_via_rest(fastapi_test_app_with_multiple_objects): + """Test sorting with invalid parameters.""" + client = fastapi_test_app_with_multiple_objects + + # Test invalid sort_order + response = client.get( + "/entities?project=demo_project&sort_by=name&sort_order=invalid" + ) + assert response.status_code == 422 # Validation error + + # Test with only sort_by (should default to asc) + response = client.get("/entities?project=demo_project&sort_by=name") + assert response.status_code == 200 + data = response.json() + entity_names = [entity["spec"]["name"] for entity in data["entities"]] + assert entity_names == sorted(entity_names) + + +def test_pagination_no_parameters_via_rest(fastapi_test_app_with_multiple_objects): + """Test that endpoints work without pagination parameters.""" + client = fastapi_test_app_with_multiple_objects + + # Test entities without pagination + response = client.get("/entities?project=demo_project") + assert response.status_code == 200 + data = response.json() + assert "entities" in data + assert "pagination" in data + # All entities should be returned (includes the dummy entity) + assert len(data["entities"]) == 6 + assert data["pagination"]["totalCount"] == 6 + assert data["pagination"]["totalPages"] == 1 + + +def test_lineage_pagination_via_rest(fastapi_test_app_with_multiple_objects): + """Test pagination for lineage endpoints.""" + client = fastapi_test_app_with_multiple_objects + + # Test lineage registry endpoint with pagination + response = client.get("/lineage/registry?project=demo_project&page=1&limit=5") + assert response.status_code == 200 + data = response.json() + assert "relationships" in data + assert "indirect_relationships" in data + assert "relationships_pagination" in data + assert "indirect_relationships_pagination" in data + + # Test object relationships endpoint with pagination + response = client.get( + "/lineage/objects/featureView/user_profile?project=demo_project&page=1&limit=5" + ) + assert response.status_code == 200 + data = response.json() + assert "relationships" in data + assert "pagination" in data + + +def test_lineage_sorting_via_rest(fastapi_test_app_with_multiple_objects): + """Test sorting for lineage endpoints.""" + client = fastapi_test_app_with_multiple_objects + + # Test lineage registry endpoint with sorting + response = client.get( + "/lineage/registry?project=demo_project&sort_by=id&sort_order=asc" + ) + assert response.status_code == 200 + data = response.json() + assert "relationships" in data + assert "indirect_relationships" in data + + # Test object relationships endpoint with sorting + response = client.get( + "/lineage/objects/featureView/user_profile?project=demo_project&sort_by=id&sort_order=asc" + ) + assert response.status_code == 200 + data = response.json() + assert "relationships" in data