// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; package google.cloud.aiplatform.v1; import "google/api/annotations.proto"; import "google/api/client.proto"; import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/cloud/aiplatform/v1/entity_type.proto"; import "google/cloud/aiplatform/v1/feature.proto"; import "google/cloud/aiplatform/v1/feature_selector.proto"; import "google/cloud/aiplatform/v1/featurestore.proto"; import "google/cloud/aiplatform/v1/io.proto"; import "google/cloud/aiplatform/v1/operation.proto"; import "google/longrunning/operations.proto"; import "google/protobuf/empty.proto"; import "google/protobuf/field_mask.proto"; import "google/protobuf/timestamp.proto"; import "google/type/interval.proto"; option csharp_namespace = "Google.Cloud.AIPlatform.V1"; option go_package = "cloud.google.com/go/aiplatform/apiv1/aiplatformpb;aiplatformpb"; option java_multiple_files = true; option java_outer_classname = "FeaturestoreServiceProto"; option java_package = "com.google.cloud.aiplatform.v1"; option php_namespace = "Google\\Cloud\\AIPlatform\\V1"; option ruby_package = "Google::Cloud::AIPlatform::V1"; // The service that handles CRUD and List for resources for Featurestore. service FeaturestoreService { option (google.api.default_host) = "aiplatform.googleapis.com"; option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; // Creates a new Featurestore in a given project and location. rpc CreateFeaturestore(CreateFeaturestoreRequest) returns (google.longrunning.Operation) { option (google.api.http) = { post: "/v1/{parent=projects/*/locations/*}/featurestores" body: "featurestore" }; option (google.api.method_signature) = "parent,featurestore"; option (google.api.method_signature) = "parent,featurestore,featurestore_id"; option (google.longrunning.operation_info) = { response_type: "Featurestore" metadata_type: "CreateFeaturestoreOperationMetadata" }; } // Gets details of a single Featurestore. rpc GetFeaturestore(GetFeaturestoreRequest) returns (Featurestore) { option (google.api.http) = { get: "/v1/{name=projects/*/locations/*/featurestores/*}" }; option (google.api.method_signature) = "name"; } // Lists Featurestores in a given project and location. rpc ListFeaturestores(ListFeaturestoresRequest) returns (ListFeaturestoresResponse) { option (google.api.http) = { get: "/v1/{parent=projects/*/locations/*}/featurestores" }; option (google.api.method_signature) = "parent"; } // Updates the parameters of a single Featurestore. rpc UpdateFeaturestore(UpdateFeaturestoreRequest) returns (google.longrunning.Operation) { option (google.api.http) = { patch: "/v1/{featurestore.name=projects/*/locations/*/featurestores/*}" body: "featurestore" }; option (google.api.method_signature) = "featurestore,update_mask"; option (google.longrunning.operation_info) = { response_type: "Featurestore" metadata_type: "UpdateFeaturestoreOperationMetadata" }; } // Deletes a single Featurestore. The Featurestore must not contain any // EntityTypes or `force` must be set to true for the request to succeed. rpc DeleteFeaturestore(DeleteFeaturestoreRequest) returns (google.longrunning.Operation) { option (google.api.http) = { delete: "/v1/{name=projects/*/locations/*/featurestores/*}" }; option (google.api.method_signature) = "name"; option (google.api.method_signature) = "name,force"; option (google.longrunning.operation_info) = { response_type: "google.protobuf.Empty" metadata_type: "DeleteOperationMetadata" }; } // Creates a new EntityType in a given Featurestore. rpc CreateEntityType(CreateEntityTypeRequest) returns (google.longrunning.Operation) { option (google.api.http) = { post: "/v1/{parent=projects/*/locations/*/featurestores/*}/entityTypes" body: "entity_type" }; option (google.api.method_signature) = "parent,entity_type"; option (google.api.method_signature) = "parent,entity_type,entity_type_id"; option (google.longrunning.operation_info) = { response_type: "EntityType" metadata_type: "CreateEntityTypeOperationMetadata" }; } // Gets details of a single EntityType. rpc GetEntityType(GetEntityTypeRequest) returns (EntityType) { option (google.api.http) = { get: "/v1/{name=projects/*/locations/*/featurestores/*/entityTypes/*}" }; option (google.api.method_signature) = "name"; } // Lists EntityTypes in a given Featurestore. rpc ListEntityTypes(ListEntityTypesRequest) returns (ListEntityTypesResponse) { option (google.api.http) = { get: "/v1/{parent=projects/*/locations/*/featurestores/*}/entityTypes" }; option (google.api.method_signature) = "parent"; } // Updates the parameters of a single EntityType. rpc UpdateEntityType(UpdateEntityTypeRequest) returns (EntityType) { option (google.api.http) = { patch: "/v1/{entity_type.name=projects/*/locations/*/featurestores/*/entityTypes/*}" body: "entity_type" }; option (google.api.method_signature) = "entity_type,update_mask"; } // Deletes a single EntityType. The EntityType must not have any Features // or `force` must be set to true for the request to succeed. rpc DeleteEntityType(DeleteEntityTypeRequest) returns (google.longrunning.Operation) { option (google.api.http) = { delete: "/v1/{name=projects/*/locations/*/featurestores/*/entityTypes/*}" }; option (google.api.method_signature) = "name"; option (google.api.method_signature) = "name,force"; option (google.longrunning.operation_info) = { response_type: "google.protobuf.Empty" metadata_type: "DeleteOperationMetadata" }; } // Creates a new Feature in a given EntityType. rpc CreateFeature(CreateFeatureRequest) returns (google.longrunning.Operation) { option (google.api.http) = { post: "/v1/{parent=projects/*/locations/*/featurestores/*/entityTypes/*}/features" body: "feature" }; option (google.api.method_signature) = "parent,feature"; option (google.api.method_signature) = "parent,feature,feature_id"; option (google.longrunning.operation_info) = { response_type: "Feature" metadata_type: "CreateFeatureOperationMetadata" }; } // Creates a batch of Features in a given EntityType. rpc BatchCreateFeatures(BatchCreateFeaturesRequest) returns (google.longrunning.Operation) { option (google.api.http) = { post: "/v1/{parent=projects/*/locations/*/featurestores/*/entityTypes/*}/features:batchCreate" body: "*" }; option (google.api.method_signature) = "parent,requests"; option (google.longrunning.operation_info) = { response_type: "BatchCreateFeaturesResponse" metadata_type: "BatchCreateFeaturesOperationMetadata" }; } // Gets details of a single Feature. rpc GetFeature(GetFeatureRequest) returns (Feature) { option (google.api.http) = { get: "/v1/{name=projects/*/locations/*/featurestores/*/entityTypes/*/features/*}" }; option (google.api.method_signature) = "name"; } // Lists Features in a given EntityType. rpc ListFeatures(ListFeaturesRequest) returns (ListFeaturesResponse) { option (google.api.http) = { get: "/v1/{parent=projects/*/locations/*/featurestores/*/entityTypes/*}/features" }; option (google.api.method_signature) = "parent"; } // Updates the parameters of a single Feature. rpc UpdateFeature(UpdateFeatureRequest) returns (Feature) { option (google.api.http) = { patch: "/v1/{feature.name=projects/*/locations/*/featurestores/*/entityTypes/*/features/*}" body: "feature" }; option (google.api.method_signature) = "feature,update_mask"; } // Deletes a single Feature. rpc DeleteFeature(DeleteFeatureRequest) returns (google.longrunning.Operation) { option (google.api.http) = { delete: "/v1/{name=projects/*/locations/*/featurestores/*/entityTypes/*/features/*}" }; option (google.api.method_signature) = "name"; option (google.longrunning.operation_info) = { response_type: "google.protobuf.Empty" metadata_type: "DeleteOperationMetadata" }; } // Imports Feature values into the Featurestore from a source storage. // // The progress of the import is tracked by the returned operation. The // imported features are guaranteed to be visible to subsequent read // operations after the operation is marked as successfully done. // // If an import operation fails, the Feature values returned from // reads and exports may be inconsistent. If consistency is // required, the caller must retry the same import request again and wait till // the new operation returned is marked as successfully done. // // There are also scenarios where the caller can cause inconsistency. // // - Source data for import contains multiple distinct Feature values for // the same entity ID and timestamp. // - Source is modified during an import. This includes adding, updating, or // removing source data and/or metadata. Examples of updating metadata // include but are not limited to changing storage location, storage class, // or retention policy. // - Online serving cluster is under-provisioned. rpc ImportFeatureValues(ImportFeatureValuesRequest) returns (google.longrunning.Operation) { option (google.api.http) = { post: "/v1/{entity_type=projects/*/locations/*/featurestores/*/entityTypes/*}:importFeatureValues" body: "*" }; option (google.api.method_signature) = "entity_type"; option (google.longrunning.operation_info) = { response_type: "ImportFeatureValuesResponse" metadata_type: "ImportFeatureValuesOperationMetadata" }; } // Batch reads Feature values from a Featurestore. // // This API enables batch reading Feature values, where each read // instance in the batch may read Feature values of entities from one or // more EntityTypes. Point-in-time correctness is guaranteed for Feature // values of each read instance as of each instance's read timestamp. rpc BatchReadFeatureValues(BatchReadFeatureValuesRequest) returns (google.longrunning.Operation) { option (google.api.http) = { post: "/v1/{featurestore=projects/*/locations/*/featurestores/*}:batchReadFeatureValues" body: "*" }; option (google.api.method_signature) = "featurestore"; option (google.longrunning.operation_info) = { response_type: "BatchReadFeatureValuesResponse" metadata_type: "BatchReadFeatureValuesOperationMetadata" }; } // Exports Feature values from all the entities of a target EntityType. rpc ExportFeatureValues(ExportFeatureValuesRequest) returns (google.longrunning.Operation) { option (google.api.http) = { post: "/v1/{entity_type=projects/*/locations/*/featurestores/*/entityTypes/*}:exportFeatureValues" body: "*" }; option (google.api.method_signature) = "entity_type"; option (google.longrunning.operation_info) = { response_type: "ExportFeatureValuesResponse" metadata_type: "ExportFeatureValuesOperationMetadata" }; } // Delete Feature values from Featurestore. // // The progress of the deletion is tracked by the returned operation. The // deleted feature values are guaranteed to be invisible to subsequent read // operations after the operation is marked as successfully done. // // If a delete feature values operation fails, the feature values // returned from reads and exports may be inconsistent. If consistency is // required, the caller must retry the same delete request again and wait till // the new operation returned is marked as successfully done. rpc DeleteFeatureValues(DeleteFeatureValuesRequest) returns (google.longrunning.Operation) { option (google.api.http) = { post: "/v1/{entity_type=projects/*/locations/*/featurestores/*/entityTypes/*}:deleteFeatureValues" body: "*" }; option (google.api.method_signature) = "entity_type"; option (google.longrunning.operation_info) = { response_type: "DeleteFeatureValuesResponse" metadata_type: "DeleteFeatureValuesOperationMetadata" }; } // Searches Features matching a query in a given project. rpc SearchFeatures(SearchFeaturesRequest) returns (SearchFeaturesResponse) { option (google.api.http) = { get: "/v1/{location=projects/*/locations/*}/featurestores:searchFeatures" }; option (google.api.method_signature) = "location"; option (google.api.method_signature) = "location,query"; } } // Request message for // [FeaturestoreService.CreateFeaturestore][google.cloud.aiplatform.v1.FeaturestoreService.CreateFeaturestore]. message CreateFeaturestoreRequest { // Required. The resource name of the Location to create Featurestores. // Format: // `projects/{project}/locations/{location}'` string parent = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { child_type: "aiplatform.googleapis.com/Featurestore" } ]; // Required. The Featurestore to create. Featurestore featurestore = 2 [(google.api.field_behavior) = REQUIRED]; // Required. The ID to use for this Featurestore, which will become the final // component of the Featurestore's resource name. // // This value may be up to 60 characters, and valid characters are // `[a-z0-9_]`. The first character cannot be a number. // // The value must be unique within the project and location. string featurestore_id = 3 [(google.api.field_behavior) = REQUIRED]; } // Request message for // [FeaturestoreService.GetFeaturestore][google.cloud.aiplatform.v1.FeaturestoreService.GetFeaturestore]. message GetFeaturestoreRequest { // Required. The name of the Featurestore resource. string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "aiplatform.googleapis.com/Featurestore" } ]; } // Request message for // [FeaturestoreService.ListFeaturestores][google.cloud.aiplatform.v1.FeaturestoreService.ListFeaturestores]. message ListFeaturestoresRequest { // Required. The resource name of the Location to list Featurestores. // Format: // `projects/{project}/locations/{location}` string parent = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { child_type: "aiplatform.googleapis.com/Featurestore" } ]; // Lists the featurestores that match the filter expression. The following // fields are supported: // // * `create_time`: Supports `=`, `!=`, `<`, `>`, `<=`, and `>=` comparisons. // Values must be // in RFC 3339 format. // * `update_time`: Supports `=`, `!=`, `<`, `>`, `<=`, and `>=` comparisons. // Values must be // in RFC 3339 format. // * `online_serving_config.fixed_node_count`: Supports `=`, `!=`, `<`, `>`, // `<=`, and `>=` comparisons. // * `labels`: Supports key-value equality and key presence. // // Examples: // // * `create_time > "2020-01-01" OR update_time > "2020-01-01"` // Featurestores created or updated after 2020-01-01. // * `labels.env = "prod"` // Featurestores with label "env" set to "prod". string filter = 2; // The maximum number of Featurestores to return. The service may return fewer // than this value. If unspecified, at most 100 Featurestores will be // returned. The maximum value is 100; any value greater than 100 will be // coerced to 100. int32 page_size = 3; // A page token, received from a previous // [FeaturestoreService.ListFeaturestores][google.cloud.aiplatform.v1.FeaturestoreService.ListFeaturestores] // call. Provide this to retrieve the subsequent page. // // When paginating, all other parameters provided to // [FeaturestoreService.ListFeaturestores][google.cloud.aiplatform.v1.FeaturestoreService.ListFeaturestores] // must match the call that provided the page token. string page_token = 4; // A comma-separated list of fields to order by, sorted in ascending order. // Use "desc" after a field name for descending. // Supported Fields: // // * `create_time` // * `update_time` // * `online_serving_config.fixed_node_count` string order_by = 5; // Mask specifying which fields to read. google.protobuf.FieldMask read_mask = 6; } // Response message for // [FeaturestoreService.ListFeaturestores][google.cloud.aiplatform.v1.FeaturestoreService.ListFeaturestores]. message ListFeaturestoresResponse { // The Featurestores matching the request. repeated Featurestore featurestores = 1; // A token, which can be sent as // [ListFeaturestoresRequest.page_token][google.cloud.aiplatform.v1.ListFeaturestoresRequest.page_token] // to retrieve the next page. If this field is omitted, there are no // subsequent pages. string next_page_token = 2; } // Request message for // [FeaturestoreService.UpdateFeaturestore][google.cloud.aiplatform.v1.FeaturestoreService.UpdateFeaturestore]. message UpdateFeaturestoreRequest { // Required. The Featurestore's `name` field is used to identify the // Featurestore to be updated. Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}` Featurestore featurestore = 1 [(google.api.field_behavior) = REQUIRED]; // Field mask is used to specify the fields to be overwritten in the // Featurestore resource by the update. // The fields specified in the update_mask are relative to the resource, not // the full request. A field will be overwritten if it is in the mask. If the // user does not provide a mask then only the non-empty fields present in the // request will be overwritten. Set the update_mask to `*` to override all // fields. // // Updatable fields: // // * `labels` // * `online_serving_config.fixed_node_count` // * `online_serving_config.scaling` // * `online_storage_ttl_days` google.protobuf.FieldMask update_mask = 2; } // Request message for // [FeaturestoreService.DeleteFeaturestore][google.cloud.aiplatform.v1.FeaturestoreService.DeleteFeaturestore]. message DeleteFeaturestoreRequest { // Required. The name of the Featurestore to be deleted. // Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}` string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "aiplatform.googleapis.com/Featurestore" } ]; // If set to true, any EntityTypes and Features for this Featurestore will // also be deleted. (Otherwise, the request will only work if the Featurestore // has no EntityTypes.) bool force = 2; } // Request message for // [FeaturestoreService.ImportFeatureValues][google.cloud.aiplatform.v1.FeaturestoreService.ImportFeatureValues]. message ImportFeatureValuesRequest { // Defines the Feature value(s) to import. message FeatureSpec { // Required. ID of the Feature to import values of. This Feature must exist // in the target EntityType, or the request will fail. string id = 1 [(google.api.field_behavior) = REQUIRED]; // Source column to get the Feature values from. If not set, uses the column // with the same name as the Feature ID. string source_field = 2; } // Details about the source data, including the location of the storage and // the format. oneof source { AvroSource avro_source = 2; BigQuerySource bigquery_source = 3; CsvSource csv_source = 4; } // Source of Feature timestamp for all Feature values of each entity. // Timestamps must be millisecond-aligned. oneof feature_time_source { // Source column that holds the Feature timestamp for all Feature // values in each entity. string feature_time_field = 6; // Single Feature timestamp for all entities being imported. The // timestamp must not have higher than millisecond precision. google.protobuf.Timestamp feature_time = 7; } // Required. The resource name of the EntityType grouping the Features for // which values are being imported. Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entityType}` string entity_type = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "aiplatform.googleapis.com/EntityType" } ]; // Source column that holds entity IDs. If not provided, entity IDs are // extracted from the column named entity_id. string entity_id_field = 5; // Required. Specifications defining which Feature values to import from the // entity. The request fails if no feature_specs are provided, and having // multiple feature_specs for one Feature is not allowed. repeated FeatureSpec feature_specs = 8 [(google.api.field_behavior) = REQUIRED]; // If set, data will not be imported for online serving. This // is typically used for backfilling, where Feature generation timestamps are // not in the timestamp range needed for online serving. bool disable_online_serving = 9; // Specifies the number of workers that are used to write data to the // Featurestore. Consider the online serving capacity that you require to // achieve the desired import throughput without interfering with online // serving. The value must be positive, and less than or equal to 100. // If not set, defaults to using 1 worker. The low count ensures minimal // impact on online serving performance. int32 worker_count = 11; // If true, API doesn't start ingestion analysis pipeline. bool disable_ingestion_analysis = 12; } // Response message for // [FeaturestoreService.ImportFeatureValues][google.cloud.aiplatform.v1.FeaturestoreService.ImportFeatureValues]. message ImportFeatureValuesResponse { // Number of entities that have been imported by the operation. int64 imported_entity_count = 1; // Number of Feature values that have been imported by the operation. int64 imported_feature_value_count = 2; // The number of rows in input source that weren't imported due to either // * Not having any featureValues. // * Having a null entityId. // * Having a null timestamp. // * Not being parsable (applicable for CSV sources). int64 invalid_row_count = 6; // The number rows that weren't ingested due to having feature timestamps // outside the retention boundary. int64 timestamp_outside_retention_rows_count = 4; } // Request message for // [FeaturestoreService.BatchReadFeatureValues][google.cloud.aiplatform.v1.FeaturestoreService.BatchReadFeatureValues]. message BatchReadFeatureValuesRequest { // Describe pass-through fields in read_instance source. message PassThroughField { // Required. The name of the field in the CSV header or the name of the // column in BigQuery table. The naming restriction is the same as // [Feature.name][google.cloud.aiplatform.v1.Feature.name]. string field_name = 1 [(google.api.field_behavior) = REQUIRED]; } // Selects Features of an EntityType to read values of and specifies read // settings. message EntityTypeSpec { // Required. ID of the EntityType to select Features. The EntityType id is // the // [entity_type_id][google.cloud.aiplatform.v1.CreateEntityTypeRequest.entity_type_id] // specified during EntityType creation. string entity_type_id = 1 [(google.api.field_behavior) = REQUIRED]; // Required. Selectors choosing which Feature values to read from the // EntityType. FeatureSelector feature_selector = 2 [(google.api.field_behavior) = REQUIRED]; // Per-Feature settings for the batch read. repeated DestinationFeatureSetting settings = 3; } oneof read_option { // Each read instance consists of exactly one read timestamp and one or more // entity IDs identifying entities of the corresponding EntityTypes whose // Features are requested. // // Each output instance contains Feature values of requested entities // concatenated together as of the read time. // // An example read instance may be `foo_entity_id, bar_entity_id, // 2020-01-01T10:00:00.123Z`. // // An example output instance may be `foo_entity_id, bar_entity_id, // 2020-01-01T10:00:00.123Z, foo_entity_feature1_value, // bar_entity_feature2_value`. // // Timestamp in each read instance must be millisecond-aligned. // // `csv_read_instances` are read instances stored in a plain-text CSV file. // The header should be: // [ENTITY_TYPE_ID1], [ENTITY_TYPE_ID2], ..., timestamp // // The columns can be in any order. // // Values in the timestamp column must use the RFC 3339 format, e.g. // `2012-07-30T10:43:17.123Z`. CsvSource csv_read_instances = 3; // Similar to csv_read_instances, but from BigQuery source. BigQuerySource bigquery_read_instances = 5; } // Required. The resource name of the Featurestore from which to query Feature // values. Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}` string featurestore = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "aiplatform.googleapis.com/Featurestore" } ]; // Required. Specifies output location and format. FeatureValueDestination destination = 4 [(google.api.field_behavior) = REQUIRED]; // When not empty, the specified fields in the *_read_instances source will be // joined as-is in the output, in addition to those fields from the // Featurestore Entity. // // For BigQuery source, the type of the pass-through values will be // automatically inferred. For CSV source, the pass-through values will be // passed as opaque bytes. repeated PassThroughField pass_through_fields = 8; // Required. Specifies EntityType grouping Features to read values of and // settings. repeated EntityTypeSpec entity_type_specs = 7 [(google.api.field_behavior) = REQUIRED]; // Optional. Excludes Feature values with feature generation timestamp before // this timestamp. If not set, retrieve oldest values kept in Feature Store. // Timestamp, if present, must not have higher than millisecond precision. google.protobuf.Timestamp start_time = 11 [(google.api.field_behavior) = OPTIONAL]; } // Request message for // [FeaturestoreService.ExportFeatureValues][google.cloud.aiplatform.v1.FeaturestoreService.ExportFeatureValues]. message ExportFeatureValuesRequest { // Describes exporting the latest Feature values of all entities of the // EntityType between [start_time, snapshot_time]. message SnapshotExport { // Exports Feature values as of this timestamp. If not set, // retrieve values as of now. Timestamp, if present, must not have higher // than millisecond precision. google.protobuf.Timestamp snapshot_time = 1; // Excludes Feature values with feature generation timestamp before this // timestamp. If not set, retrieve oldest values kept in Feature Store. // Timestamp, if present, must not have higher than millisecond precision. google.protobuf.Timestamp start_time = 2; } // Describes exporting all historical Feature values of all entities of the // EntityType between [start_time, end_time]. message FullExport { // Excludes Feature values with feature generation timestamp before this // timestamp. If not set, retrieve oldest values kept in Feature Store. // Timestamp, if present, must not have higher than millisecond precision. google.protobuf.Timestamp start_time = 2; // Exports Feature values as of this timestamp. If not set, // retrieve values as of now. Timestamp, if present, must not have higher // than millisecond precision. google.protobuf.Timestamp end_time = 1; } // Required. The mode in which Feature values are exported. oneof mode { // Exports the latest Feature values of all entities of the EntityType // within a time range. SnapshotExport snapshot_export = 3; // Exports all historical values of all entities of the EntityType within a // time range FullExport full_export = 7; } // Required. The resource name of the EntityType from which to export Feature // values. Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}` string entity_type = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "aiplatform.googleapis.com/EntityType" } ]; // Required. Specifies destination location and format. FeatureValueDestination destination = 4 [(google.api.field_behavior) = REQUIRED]; // Required. Selects Features to export values of. FeatureSelector feature_selector = 5 [(google.api.field_behavior) = REQUIRED]; // Per-Feature export settings. repeated DestinationFeatureSetting settings = 6; } message DestinationFeatureSetting { // Required. The ID of the Feature to apply the setting to. string feature_id = 1 [(google.api.field_behavior) = REQUIRED]; // Specify the field name in the export destination. If not specified, // Feature ID is used. string destination_field = 2; } // A destination location for Feature values and format. message FeatureValueDestination { oneof destination { // Output in BigQuery format. // [BigQueryDestination.output_uri][google.cloud.aiplatform.v1.BigQueryDestination.output_uri] // in // [FeatureValueDestination.bigquery_destination][google.cloud.aiplatform.v1.FeatureValueDestination.bigquery_destination] // must refer to a table. BigQueryDestination bigquery_destination = 1; // Output in TFRecord format. // // Below are the mapping from Feature value type // in Featurestore to Feature value type in TFRecord: // // Value type in Featurestore | Value type in TFRecord // DOUBLE, DOUBLE_ARRAY | FLOAT_LIST // INT64, INT64_ARRAY | INT64_LIST // STRING, STRING_ARRAY, BYTES | BYTES_LIST // true -> byte_string("true"), false -> byte_string("false") // BOOL, BOOL_ARRAY (true, false) | BYTES_LIST TFRecordDestination tfrecord_destination = 2; // Output in CSV format. Array Feature value types are not allowed in CSV // format. CsvDestination csv_destination = 3; } } // Response message for // [FeaturestoreService.ExportFeatureValues][google.cloud.aiplatform.v1.FeaturestoreService.ExportFeatureValues]. message ExportFeatureValuesResponse {} // Response message for // [FeaturestoreService.BatchReadFeatureValues][google.cloud.aiplatform.v1.FeaturestoreService.BatchReadFeatureValues]. message BatchReadFeatureValuesResponse {} // Request message for // [FeaturestoreService.CreateEntityType][google.cloud.aiplatform.v1.FeaturestoreService.CreateEntityType]. message CreateEntityTypeRequest { // Required. The resource name of the Featurestore to create EntityTypes. // Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}` string parent = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "aiplatform.googleapis.com/Featurestore" } ]; // The EntityType to create. EntityType entity_type = 2; // Required. The ID to use for the EntityType, which will become the final // component of the EntityType's resource name. // // This value may be up to 60 characters, and valid characters are // `[a-z0-9_]`. The first character cannot be a number. // // The value must be unique within a featurestore. string entity_type_id = 3 [(google.api.field_behavior) = REQUIRED]; } // Request message for // [FeaturestoreService.GetEntityType][google.cloud.aiplatform.v1.FeaturestoreService.GetEntityType]. message GetEntityTypeRequest { // Required. The name of the EntityType resource. // Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}` string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "aiplatform.googleapis.com/EntityType" } ]; } // Request message for // [FeaturestoreService.ListEntityTypes][google.cloud.aiplatform.v1.FeaturestoreService.ListEntityTypes]. message ListEntityTypesRequest { // Required. The resource name of the Featurestore to list EntityTypes. // Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}` string parent = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { child_type: "aiplatform.googleapis.com/EntityType" } ]; // Lists the EntityTypes that match the filter expression. The following // filters are supported: // // * `create_time`: Supports `=`, `!=`, `<`, `>`, `>=`, and `<=` comparisons. // Values must be in RFC 3339 format. // * `update_time`: Supports `=`, `!=`, `<`, `>`, `>=`, and `<=` comparisons. // Values must be in RFC 3339 format. // * `labels`: Supports key-value equality as well as key presence. // // Examples: // // * `create_time > \"2020-01-31T15:30:00.000000Z\" OR // update_time > \"2020-01-31T15:30:00.000000Z\"` --> EntityTypes created // or updated after 2020-01-31T15:30:00.000000Z. // * `labels.active = yes AND labels.env = prod` --> EntityTypes having both // (active: yes) and (env: prod) labels. // * `labels.env: *` --> Any EntityType which has a label with 'env' as the // key. string filter = 2; // The maximum number of EntityTypes to return. The service may return fewer // than this value. If unspecified, at most 1000 EntityTypes will be returned. // The maximum value is 1000; any value greater than 1000 will be coerced to // 1000. int32 page_size = 3; // A page token, received from a previous // [FeaturestoreService.ListEntityTypes][google.cloud.aiplatform.v1.FeaturestoreService.ListEntityTypes] // call. Provide this to retrieve the subsequent page. // // When paginating, all other parameters provided to // [FeaturestoreService.ListEntityTypes][google.cloud.aiplatform.v1.FeaturestoreService.ListEntityTypes] // must match the call that provided the page token. string page_token = 4; // A comma-separated list of fields to order by, sorted in ascending order. // Use "desc" after a field name for descending. // // Supported fields: // // * `entity_type_id` // * `create_time` // * `update_time` string order_by = 5; // Mask specifying which fields to read. google.protobuf.FieldMask read_mask = 6; } // Response message for // [FeaturestoreService.ListEntityTypes][google.cloud.aiplatform.v1.FeaturestoreService.ListEntityTypes]. message ListEntityTypesResponse { // The EntityTypes matching the request. repeated EntityType entity_types = 1; // A token, which can be sent as // [ListEntityTypesRequest.page_token][google.cloud.aiplatform.v1.ListEntityTypesRequest.page_token] // to retrieve the next page. If this field is omitted, there are no // subsequent pages. string next_page_token = 2; } // Request message for // [FeaturestoreService.UpdateEntityType][google.cloud.aiplatform.v1.FeaturestoreService.UpdateEntityType]. message UpdateEntityTypeRequest { // Required. The EntityType's `name` field is used to identify the EntityType // to be updated. Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}` EntityType entity_type = 1 [(google.api.field_behavior) = REQUIRED]; // Field mask is used to specify the fields to be overwritten in the // EntityType resource by the update. // The fields specified in the update_mask are relative to the resource, not // the full request. A field will be overwritten if it is in the mask. If the // user does not provide a mask then only the non-empty fields present in the // request will be overwritten. Set the update_mask to `*` to override all // fields. // // Updatable fields: // // * `description` // * `labels` // * `monitoring_config.snapshot_analysis.disabled` // * `monitoring_config.snapshot_analysis.monitoring_interval_days` // * `monitoring_config.snapshot_analysis.staleness_days` // * `monitoring_config.import_features_analysis.state` // * `monitoring_config.import_features_analysis.anomaly_detection_baseline` // * `monitoring_config.numerical_threshold_config.value` // * `monitoring_config.categorical_threshold_config.value` // * `offline_storage_ttl_days` google.protobuf.FieldMask update_mask = 2; } // Request message for [FeaturestoreService.DeleteEntityTypes][]. message DeleteEntityTypeRequest { // Required. The name of the EntityType to be deleted. // Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}` string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "aiplatform.googleapis.com/EntityType" } ]; // If set to true, any Features for this EntityType will also be deleted. // (Otherwise, the request will only work if the EntityType has no Features.) bool force = 2; } // Request message for // [FeaturestoreService.CreateFeature][google.cloud.aiplatform.v1.FeaturestoreService.CreateFeature]. message CreateFeatureRequest { // Required. The resource name of the EntityType to create a Feature. // Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}` string parent = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "aiplatform.googleapis.com/EntityType" } ]; // Required. The Feature to create. Feature feature = 2 [(google.api.field_behavior) = REQUIRED]; // Required. The ID to use for the Feature, which will become the final // component of the Feature's resource name. // // This value may be up to 128 characters, and valid characters are // `[a-z0-9_]`. The first character cannot be a number. // // The value must be unique within an EntityType. string feature_id = 3 [(google.api.field_behavior) = REQUIRED]; } // Request message for // [FeaturestoreService.BatchCreateFeatures][google.cloud.aiplatform.v1.FeaturestoreService.BatchCreateFeatures]. message BatchCreateFeaturesRequest { // Required. The resource name of the EntityType to create the batch of // Features under. Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}` string parent = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "aiplatform.googleapis.com/EntityType" } ]; // Required. The request message specifying the Features to create. All // Features must be created under the same parent EntityType. The `parent` // field in each child request message can be omitted. If `parent` is set in a // child request, then the value must match the `parent` value in this request // message. repeated CreateFeatureRequest requests = 2 [(google.api.field_behavior) = REQUIRED]; } // Response message for // [FeaturestoreService.BatchCreateFeatures][google.cloud.aiplatform.v1.FeaturestoreService.BatchCreateFeatures]. message BatchCreateFeaturesResponse { // The Features created. repeated Feature features = 1; } // Request message for // [FeaturestoreService.GetFeature][google.cloud.aiplatform.v1.FeaturestoreService.GetFeature]. message GetFeatureRequest { // Required. The name of the Feature resource. // Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}` string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "aiplatform.googleapis.com/Feature" } ]; } // Request message for // [FeaturestoreService.ListFeatures][google.cloud.aiplatform.v1.FeaturestoreService.ListFeatures]. message ListFeaturesRequest { // Required. The resource name of the Location to list Features. // Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}` string parent = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { child_type: "aiplatform.googleapis.com/Feature" } ]; // Lists the Features that match the filter expression. The following // filters are supported: // // * `value_type`: Supports = and != comparisons. // * `create_time`: Supports =, !=, <, >, >=, and <= comparisons. Values must // be in RFC 3339 format. // * `update_time`: Supports =, !=, <, >, >=, and <= comparisons. Values must // be in RFC 3339 format. // * `labels`: Supports key-value equality as well as key presence. // // Examples: // // * `value_type = DOUBLE` --> Features whose type is DOUBLE. // * `create_time > \"2020-01-31T15:30:00.000000Z\" OR // update_time > \"2020-01-31T15:30:00.000000Z\"` --> EntityTypes created // or updated after 2020-01-31T15:30:00.000000Z. // * `labels.active = yes AND labels.env = prod` --> Features having both // (active: yes) and (env: prod) labels. // * `labels.env: *` --> Any Feature which has a label with 'env' as the // key. string filter = 2; // The maximum number of Features to return. The service may return fewer // than this value. If unspecified, at most 1000 Features will be returned. // The maximum value is 1000; any value greater than 1000 will be coerced to // 1000. int32 page_size = 3; // A page token, received from a previous // [FeaturestoreService.ListFeatures][google.cloud.aiplatform.v1.FeaturestoreService.ListFeatures] // call. Provide this to retrieve the subsequent page. // // When paginating, all other parameters provided to // [FeaturestoreService.ListFeatures][google.cloud.aiplatform.v1.FeaturestoreService.ListFeatures] // must match the call that provided the page token. string page_token = 4; // A comma-separated list of fields to order by, sorted in ascending order. // Use "desc" after a field name for descending. // Supported fields: // // * `feature_id` // * `value_type` // * `create_time` // * `update_time` string order_by = 5; // Mask specifying which fields to read. google.protobuf.FieldMask read_mask = 6; // If set, return the most recent // [ListFeaturesRequest.latest_stats_count][google.cloud.aiplatform.v1.ListFeaturesRequest.latest_stats_count] // of stats for each Feature in response. Valid value is [0, 10]. If number of // stats exists < // [ListFeaturesRequest.latest_stats_count][google.cloud.aiplatform.v1.ListFeaturesRequest.latest_stats_count], // return all existing stats. int32 latest_stats_count = 7; } // Response message for // [FeaturestoreService.ListFeatures][google.cloud.aiplatform.v1.FeaturestoreService.ListFeatures]. message ListFeaturesResponse { // The Features matching the request. repeated Feature features = 1; // A token, which can be sent as // [ListFeaturesRequest.page_token][google.cloud.aiplatform.v1.ListFeaturesRequest.page_token] // to retrieve the next page. If this field is omitted, there are no // subsequent pages. string next_page_token = 2; } // Request message for // [FeaturestoreService.SearchFeatures][google.cloud.aiplatform.v1.FeaturestoreService.SearchFeatures]. message SearchFeaturesRequest { // Required. The resource name of the Location to search Features. // Format: // `projects/{project}/locations/{location}` string location = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "locations.googleapis.com/Location" } ]; // Query string that is a conjunction of field-restricted queries and/or // field-restricted filters. Field-restricted queries and filters can be // combined using `AND` to form a conjunction. // // A field query is in the form FIELD:QUERY. This implicitly checks if QUERY // exists as a substring within Feature's FIELD. The QUERY // and the FIELD are converted to a sequence of words (i.e. tokens) for // comparison. This is done by: // // * Removing leading/trailing whitespace and tokenizing the search value. // Characters that are not one of alphanumeric `[a-zA-Z0-9]`, underscore // `_`, or asterisk `*` are treated as delimiters for tokens. `*` is treated // as a wildcard that matches characters within a token. // * Ignoring case. // * Prepending an asterisk to the first and appending an asterisk to the // last token in QUERY. // // A QUERY must be either a singular token or a phrase. A phrase is one or // multiple words enclosed in double quotation marks ("). With phrases, the // order of the words is important. Words in the phrase must be matching in // order and consecutively. // // Supported FIELDs for field-restricted queries: // // * `feature_id` // * `description` // * `entity_type_id` // // Examples: // // * `feature_id: foo` --> Matches a Feature with ID containing the substring // `foo` (eg. `foo`, `foofeature`, `barfoo`). // * `feature_id: foo*feature` --> Matches a Feature with ID containing the // substring `foo*feature` (eg. `foobarfeature`). // * `feature_id: foo AND description: bar` --> Matches a Feature with ID // containing the substring `foo` and description containing the substring // `bar`. // // // Besides field queries, the following exact-match filters are // supported. The exact-match filters do not support wildcards. Unlike // field-restricted queries, exact-match filters are case-sensitive. // // * `feature_id`: Supports = comparisons. // * `description`: Supports = comparisons. Multi-token filters should be // enclosed in quotes. // * `entity_type_id`: Supports = comparisons. // * `value_type`: Supports = and != comparisons. // * `labels`: Supports key-value equality as well as key presence. // * `featurestore_id`: Supports = comparisons. // // Examples: // * `description = "foo bar"` --> Any Feature with description exactly equal // to `foo bar` // * `value_type = DOUBLE` --> Features whose type is DOUBLE. // * `labels.active = yes AND labels.env = prod` --> Features having both // (active: yes) and (env: prod) labels. // * `labels.env: *` --> Any Feature which has a label with `env` as the // key. string query = 3; // The maximum number of Features to return. The service may return fewer // than this value. If unspecified, at most 100 Features will be returned. // The maximum value is 100; any value greater than 100 will be coerced to // 100. int32 page_size = 4; // A page token, received from a previous // [FeaturestoreService.SearchFeatures][google.cloud.aiplatform.v1.FeaturestoreService.SearchFeatures] // call. Provide this to retrieve the subsequent page. // // When paginating, all other parameters provided to // [FeaturestoreService.SearchFeatures][google.cloud.aiplatform.v1.FeaturestoreService.SearchFeatures], // except `page_size`, must match the call that provided the page token. string page_token = 5; } // Response message for // [FeaturestoreService.SearchFeatures][google.cloud.aiplatform.v1.FeaturestoreService.SearchFeatures]. message SearchFeaturesResponse { // The Features matching the request. // // Fields returned: // // * `name` // * `description` // * `labels` // * `create_time` // * `update_time` repeated Feature features = 1; // A token, which can be sent as // [SearchFeaturesRequest.page_token][google.cloud.aiplatform.v1.SearchFeaturesRequest.page_token] // to retrieve the next page. If this field is omitted, there are no // subsequent pages. string next_page_token = 2; } // Request message for // [FeaturestoreService.UpdateFeature][google.cloud.aiplatform.v1.FeaturestoreService.UpdateFeature]. message UpdateFeatureRequest { // Required. The Feature's `name` field is used to identify the Feature to be // updated. // Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}/features/{feature}` Feature feature = 1 [(google.api.field_behavior) = REQUIRED]; // Field mask is used to specify the fields to be overwritten in the // Features resource by the update. // The fields specified in the update_mask are relative to the resource, not // the full request. A field will be overwritten if it is in the mask. If the // user does not provide a mask then only the non-empty fields present in the // request will be overwritten. Set the update_mask to `*` to override all // fields. // // Updatable fields: // // * `description` // * `labels` // * `disable_monitoring` google.protobuf.FieldMask update_mask = 2; } // Request message for // [FeaturestoreService.DeleteFeature][google.cloud.aiplatform.v1.FeaturestoreService.DeleteFeature]. message DeleteFeatureRequest { // Required. The name of the Features to be deleted. // Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entity_type}/features/{feature}` string name = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "aiplatform.googleapis.com/Feature" } ]; } // Details of operations that perform create Featurestore. message CreateFeaturestoreOperationMetadata { // Operation metadata for Featurestore. GenericOperationMetadata generic_metadata = 1; } // Details of operations that perform update Featurestore. message UpdateFeaturestoreOperationMetadata { // Operation metadata for Featurestore. GenericOperationMetadata generic_metadata = 1; } // Details of operations that perform import Feature values. message ImportFeatureValuesOperationMetadata { // Operation metadata for Featurestore import Feature values. GenericOperationMetadata generic_metadata = 1; // Number of entities that have been imported by the operation. int64 imported_entity_count = 2; // Number of Feature values that have been imported by the operation. int64 imported_feature_value_count = 3; // The source URI from where Feature values are imported. repeated string source_uris = 4; // The number of rows in input source that weren't imported due to either // * Not having any featureValues. // * Having a null entityId. // * Having a null timestamp. // * Not being parsable (applicable for CSV sources). int64 invalid_row_count = 6; // The number rows that weren't ingested due to having timestamps outside the // retention boundary. int64 timestamp_outside_retention_rows_count = 7; // List of ImportFeatureValues operations running under a single EntityType // that are blocking this operation. repeated int64 blocking_operation_ids = 8; } // Details of operations that exports Features values. message ExportFeatureValuesOperationMetadata { // Operation metadata for Featurestore export Feature values. GenericOperationMetadata generic_metadata = 1; } // Details of operations that batch reads Feature values. message BatchReadFeatureValuesOperationMetadata { // Operation metadata for Featurestore batch read Features values. GenericOperationMetadata generic_metadata = 1; } // Details of operations that delete Feature values. message DeleteFeatureValuesOperationMetadata { // Operation metadata for Featurestore delete Features values. GenericOperationMetadata generic_metadata = 1; } // Details of operations that perform create EntityType. message CreateEntityTypeOperationMetadata { // Operation metadata for EntityType. GenericOperationMetadata generic_metadata = 1; } // Details of operations that perform create Feature. message CreateFeatureOperationMetadata { // Operation metadata for Feature. GenericOperationMetadata generic_metadata = 1; } // Details of operations that perform batch create Features. message BatchCreateFeaturesOperationMetadata { // Operation metadata for Feature. GenericOperationMetadata generic_metadata = 1; } // Request message for // [FeaturestoreService.DeleteFeatureValues][google.cloud.aiplatform.v1.FeaturestoreService.DeleteFeatureValues]. message DeleteFeatureValuesRequest { // Message to select entity. // If an entity id is selected, all the feature values corresponding to the // entity id will be deleted, including the entityId. message SelectEntity { // Required. Selectors choosing feature values of which entity id to be // deleted from the EntityType. EntityIdSelector entity_id_selector = 1 [(google.api.field_behavior) = REQUIRED]; } // Message to select time range and feature. // Values of the selected feature generated within an inclusive time range // will be deleted. Using this option permanently deletes the feature values // from the specified feature IDs within the specified time range. // This might include data from the online storage. If you want to retain // any deleted historical data in the online storage, you must re-ingest it. message SelectTimeRangeAndFeature { // Required. Select feature generated within a half-inclusive time range. // The time range is lower inclusive and upper exclusive. google.type.Interval time_range = 1 [(google.api.field_behavior) = REQUIRED]; // Required. Selectors choosing which feature values to be deleted from the // EntityType. FeatureSelector feature_selector = 2 [(google.api.field_behavior) = REQUIRED]; // If set, data will not be deleted from online storage. // When time range is older than the data in online storage, setting this to // be true will make the deletion have no impact on online serving. bool skip_online_storage_delete = 3; } // Defines options to select feature values to be deleted. oneof DeleteOption { // Select feature values to be deleted by specifying entities. SelectEntity select_entity = 2; // Select feature values to be deleted by specifying time range and // features. SelectTimeRangeAndFeature select_time_range_and_feature = 3; } // Required. The resource name of the EntityType grouping the Features for // which values are being deleted from. Format: // `projects/{project}/locations/{location}/featurestores/{featurestore}/entityTypes/{entityType}` string entity_type = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "aiplatform.googleapis.com/EntityType" } ]; } // Response message for // [FeaturestoreService.DeleteFeatureValues][google.cloud.aiplatform.v1.FeaturestoreService.DeleteFeatureValues]. message DeleteFeatureValuesResponse { // Response message if the request uses the SelectEntity option. message SelectEntity { // The count of deleted entity rows in the offline storage. // Each row corresponds to the combination of an entity ID and a timestamp. // One entity ID can have multiple rows in the offline storage. int64 offline_storage_deleted_entity_row_count = 1; // The count of deleted entities in the online storage. // Each entity ID corresponds to one entity. int64 online_storage_deleted_entity_count = 2; } // Response message if the request uses the SelectTimeRangeAndFeature option. message SelectTimeRangeAndFeature { // The count of the features or columns impacted. // This is the same as the feature count in the request. int64 impacted_feature_count = 1; // The count of modified entity rows in the offline storage. // Each row corresponds to the combination of an entity ID and a timestamp. // One entity ID can have multiple rows in the offline storage. // Within each row, only the features specified in the request are // deleted. int64 offline_storage_modified_entity_row_count = 2; // The count of modified entities in the online storage. // Each entity ID corresponds to one entity. // Within each entity, only the features specified in the request are // deleted. int64 online_storage_modified_entity_count = 3; } // Response based on which delete option is specified in the // request oneof response { // Response for request specifying the entities to delete SelectEntity select_entity = 1; // Response for request specifying time range and feature SelectTimeRangeAndFeature select_time_range_and_feature = 2; } } // Selector for entityId. Getting ids from the given source. message EntityIdSelector { // Details about the source data, including the location of the storage and // the format. oneof EntityIdsSource { // Source of Csv CsvSource csv_source = 3; } // Source column that holds entity IDs. If not provided, entity IDs are // extracted from the column named entity_id. string entity_id_field = 5; }