From a636c05a88560b100b58776ea1f2b4840f41f2f1 Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:41:00 -0700 Subject: [PATCH 01/25] changes without context autosynth cannot find the source of changes triggered by earlier changes in this repository, or by version upgrades to tools such as linters. --- docs/automl_v1beta1/services.rst | 3 - google/cloud/automl_v1beta1/__init__.py | 4 +- .../proto/annotation_payload.proto | 77 ++ .../proto/annotation_spec.proto | 48 + .../automl_v1beta1/proto/classification.proto | 216 ++++ .../automl_v1beta1/proto/column_spec.proto | 78 ++ .../automl_v1beta1/proto/data_items.proto | 221 ++++ .../automl_v1beta1/proto/data_stats.proto | 166 +++ .../automl_v1beta1/proto/data_types.proto | 105 ++ .../cloud/automl_v1beta1/proto/dataset.proto | 96 ++ .../automl_v1beta1/proto/detection.proto | 135 ++ .../cloud/automl_v1beta1/proto/geometry.proto | 46 + google/cloud/automl_v1beta1/proto/image.proto | 193 +++ google/cloud/automl_v1beta1/proto/io.proto | 1132 +++++++++++++++++ google/cloud/automl_v1beta1/proto/model.proto | 108 ++ .../proto/model_evaluation.proto | 116 ++ .../automl_v1beta1/proto/operations.proto | 189 +++ .../proto/prediction_service.proto | 268 ++++ .../cloud/automl_v1beta1/proto/ranges.proto | 35 + .../automl_v1beta1/proto/regression.proto | 44 + .../cloud/automl_v1beta1/proto/service.proto | 800 ++++++++++++ .../automl_v1beta1/proto/table_spec.proto | 78 ++ .../cloud/automl_v1beta1/proto/tables.proto | 292 +++++ .../cloud/automl_v1beta1/proto/temporal.proto | 37 + google/cloud/automl_v1beta1/proto/text.proto | 65 + .../proto/text_extraction.proto | 68 + .../automl_v1beta1/proto/text_segment.proto | 41 + .../automl_v1beta1/proto/text_sentiment.proto | 80 ++ .../automl_v1beta1/proto/translation.proto | 69 + google/cloud/automl_v1beta1/proto/video.proto | 48 + .../services/auto_ml/async_client.py | 4 +- noxfile.py | 34 - synth.metadata | 220 +++- .../unit/gapic/automl_v1beta1/test_auto_ml.py | 48 +- 34 files changed, 5097 insertions(+), 67 deletions(-) create mode 100644 google/cloud/automl_v1beta1/proto/annotation_payload.proto create mode 100644 google/cloud/automl_v1beta1/proto/annotation_spec.proto create mode 100644 google/cloud/automl_v1beta1/proto/classification.proto create mode 100644 google/cloud/automl_v1beta1/proto/column_spec.proto create mode 100644 google/cloud/automl_v1beta1/proto/data_items.proto create mode 100644 google/cloud/automl_v1beta1/proto/data_stats.proto create mode 100644 google/cloud/automl_v1beta1/proto/data_types.proto create mode 100644 google/cloud/automl_v1beta1/proto/dataset.proto create mode 100644 google/cloud/automl_v1beta1/proto/detection.proto create mode 100644 google/cloud/automl_v1beta1/proto/geometry.proto create mode 100644 google/cloud/automl_v1beta1/proto/image.proto create mode 100644 google/cloud/automl_v1beta1/proto/io.proto create mode 100644 google/cloud/automl_v1beta1/proto/model.proto create mode 100644 google/cloud/automl_v1beta1/proto/model_evaluation.proto create mode 100644 google/cloud/automl_v1beta1/proto/operations.proto create mode 100644 google/cloud/automl_v1beta1/proto/prediction_service.proto create mode 100644 google/cloud/automl_v1beta1/proto/ranges.proto create mode 100644 google/cloud/automl_v1beta1/proto/regression.proto create mode 100644 google/cloud/automl_v1beta1/proto/service.proto create mode 100644 google/cloud/automl_v1beta1/proto/table_spec.proto create mode 100644 google/cloud/automl_v1beta1/proto/tables.proto create mode 100644 google/cloud/automl_v1beta1/proto/temporal.proto create mode 100644 google/cloud/automl_v1beta1/proto/text.proto create mode 100644 google/cloud/automl_v1beta1/proto/text_extraction.proto create mode 100644 google/cloud/automl_v1beta1/proto/text_segment.proto create mode 100644 google/cloud/automl_v1beta1/proto/text_sentiment.proto create mode 100644 google/cloud/automl_v1beta1/proto/translation.proto create mode 100644 google/cloud/automl_v1beta1/proto/video.proto diff --git a/docs/automl_v1beta1/services.rst b/docs/automl_v1beta1/services.rst index 787e8566..9fa5c54f 100644 --- a/docs/automl_v1beta1/services.rst +++ b/docs/automl_v1beta1/services.rst @@ -7,6 +7,3 @@ Services for Google Cloud Automl v1beta1 API .. automodule:: google.cloud.automl_v1beta1.services.prediction_service :members: :inherited-members: -.. automodule:: google.cloud.automl_v1beta1.services.tables - :members: - :inherited-members: diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 904a45aa..30db2703 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -17,8 +17,8 @@ from .services.auto_ml import AutoMlClient from .services.prediction_service import PredictionServiceClient -from .services.tables.gcs_client import GcsClient -from .services.tables.tables_client import TablesClient +from .tables.gcs_client import GcsClient +from .tables.tables_client import TablesClient from .types.annotation_payload import AnnotationPayload from .types.annotation_spec import AnnotationSpec from .types.classification import ClassificationAnnotation diff --git a/google/cloud/automl_v1beta1/proto/annotation_payload.proto b/google/cloud/automl_v1beta1/proto/annotation_payload.proto new file mode 100644 index 00000000..f62bb269 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/annotation_payload.proto @@ -0,0 +1,77 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/cloud/automl/v1beta1/detection.proto"; +import "google/cloud/automl/v1beta1/tables.proto"; +import "google/cloud/automl/v1beta1/text_extraction.proto"; +import "google/cloud/automl/v1beta1/text_sentiment.proto"; +import "google/cloud/automl/v1beta1/translation.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Contains annotation information that is relevant to AutoML. +message AnnotationPayload { + // Output only . Additional information about the annotation + // specific to the AutoML domain. + oneof detail { + // Annotation details for translation. + TranslationAnnotation translation = 2; + + // Annotation details for content or image classification. + ClassificationAnnotation classification = 3; + + // Annotation details for image object detection. + ImageObjectDetectionAnnotation image_object_detection = 4; + + // Annotation details for video classification. + // Returned for Video Classification predictions. + VideoClassificationAnnotation video_classification = 9; + + // Annotation details for video object tracking. + VideoObjectTrackingAnnotation video_object_tracking = 8; + + // Annotation details for text extraction. + TextExtractionAnnotation text_extraction = 6; + + // Annotation details for text sentiment. + TextSentimentAnnotation text_sentiment = 7; + + // Annotation details for Tables. + TablesAnnotation tables = 10; + } + + // Output only . The resource ID of the annotation spec that + // this annotation pertains to. The annotation spec comes from either an + // ancestor dataset, or the dataset that was used to train the model in use. + string annotation_spec_id = 1; + + // Output only. The value of + // [display_name][google.cloud.automl.v1beta1.AnnotationSpec.display_name] + // when the model was trained. Because this field returns a value at model + // training time, for different models trained using the same dataset, the + // returned value could be different as model owner could update the + // `display_name` between any two model training. + string display_name = 5; +} diff --git a/google/cloud/automl_v1beta1/proto/annotation_spec.proto b/google/cloud/automl_v1beta1/proto/annotation_spec.proto new file mode 100644 index 00000000..d9df07ee --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/annotation_spec.proto @@ -0,0 +1,48 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A definition of an annotation spec. +message AnnotationSpec { + option (google.api.resource) = { + type: "automl.googleapis.com/AnnotationSpec" + pattern: "projects/{project}/locations/{location}/datasets/{dataset}/annotationSpecs/{annotation_spec}" + }; + + // Output only. Resource name of the annotation spec. + // Form: + // + // 'projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/annotationSpecs/{annotation_spec_id}' + string name = 1; + + // Required. The name of the annotation spec to show in the interface. The name can be + // up to 32 characters long and must match the regexp `[a-zA-Z0-9_]+`. + string display_name = 2; + + // Output only. The number of examples in the parent dataset + // labeled by the annotation spec. + int32 example_count = 9; +} diff --git a/google/cloud/automl_v1beta1/proto/classification.proto b/google/cloud/automl_v1beta1/proto/classification.proto new file mode 100644 index 00000000..0594d01e --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/classification.proto @@ -0,0 +1,216 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/temporal.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_outer_classname = "ClassificationProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Type of the classification problem. +enum ClassificationType { + // An un-set value of this enum. + CLASSIFICATION_TYPE_UNSPECIFIED = 0; + + // At most one label is allowed per example. + MULTICLASS = 1; + + // Multiple labels are allowed for one example. + MULTILABEL = 2; +} + +// Contains annotation details specific to classification. +message ClassificationAnnotation { + // Output only. A confidence estimate between 0.0 and 1.0. A higher value + // means greater confidence that the annotation is positive. If a user + // approves an annotation as negative or positive, the score value remains + // unchanged. If a user creates an annotation, the score is 0 for negative or + // 1 for positive. + float score = 1; +} + +// Contains annotation details specific to video classification. +message VideoClassificationAnnotation { + // Output only. Expresses the type of video classification. Possible values: + // + // * `segment` - Classification done on a specified by user + // time segment of a video. AnnotationSpec is answered to be present + // in that time segment, if it is present in any part of it. The video + // ML model evaluations are done only for this type of classification. + // + // * `shot`- Shot-level classification. + // AutoML Video Intelligence determines the boundaries + // for each camera shot in the entire segment of the video that user + // specified in the request configuration. AutoML Video Intelligence + // then returns labels and their confidence scores for each detected + // shot, along with the start and end time of the shot. + // WARNING: Model evaluation is not done for this classification type, + // the quality of it depends on training data, but there are no + // metrics provided to describe that quality. + // + // * `1s_interval` - AutoML Video Intelligence returns labels and their + // confidence scores for each second of the entire segment of the video + // that user specified in the request configuration. + // WARNING: Model evaluation is not done for this classification type, + // the quality of it depends on training data, but there are no + // metrics provided to describe that quality. + string type = 1; + + // Output only . The classification details of this annotation. + ClassificationAnnotation classification_annotation = 2; + + // Output only . The time segment of the video to which the + // annotation applies. + TimeSegment time_segment = 3; +} + +// Model evaluation metrics for classification problems. +// Note: For Video Classification this metrics only describe quality of the +// Video Classification predictions of "segment_classification" type. +message ClassificationEvaluationMetrics { + // Metrics for a single confidence threshold. + message ConfidenceMetricsEntry { + // Output only. Metrics are computed with an assumption that the model + // never returns predictions with score lower than this value. + float confidence_threshold = 1; + + // Output only. Metrics are computed with an assumption that the model + // always returns at most this many predictions (ordered by their score, + // descendingly), but they all still need to meet the confidence_threshold. + int32 position_threshold = 14; + + // Output only. Recall (True Positive Rate) for the given confidence + // threshold. + float recall = 2; + + // Output only. Precision for the given confidence threshold. + float precision = 3; + + // Output only. False Positive Rate for the given confidence threshold. + float false_positive_rate = 8; + + // Output only. The harmonic mean of recall and precision. + float f1_score = 4; + + // Output only. The Recall (True Positive Rate) when only considering the + // label that has the highest prediction score and not below the confidence + // threshold for each example. + float recall_at1 = 5; + + // Output only. The precision when only considering the label that has the + // highest prediction score and not below the confidence threshold for each + // example. + float precision_at1 = 6; + + // Output only. The False Positive Rate when only considering the label that + // has the highest prediction score and not below the confidence threshold + // for each example. + float false_positive_rate_at1 = 9; + + // Output only. The harmonic mean of [recall_at1][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfidenceMetricsEntry.recall_at1] and [precision_at1][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfidenceMetricsEntry.precision_at1]. + float f1_score_at1 = 7; + + // Output only. The number of model created labels that match a ground truth + // label. + int64 true_positive_count = 10; + + // Output only. The number of model created labels that do not match a + // ground truth label. + int64 false_positive_count = 11; + + // Output only. The number of ground truth labels that are not matched + // by a model created label. + int64 false_negative_count = 12; + + // Output only. The number of labels that were not created by the model, + // but if they would, they would not match a ground truth label. + int64 true_negative_count = 13; + } + + // Confusion matrix of the model running the classification. + message ConfusionMatrix { + // Output only. A row in the confusion matrix. + message Row { + // Output only. Value of the specific cell in the confusion matrix. + // The number of values each row has (i.e. the length of the row) is equal + // to the length of the `annotation_spec_id` field or, if that one is not + // populated, length of the [display_name][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfusionMatrix.display_name] field. + repeated int32 example_count = 1; + } + + // Output only. IDs of the annotation specs used in the confusion matrix. + // For Tables CLASSIFICATION + // + // [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] + // only list of [annotation_spec_display_name-s][] is populated. + repeated string annotation_spec_id = 1; + + // Output only. Display name of the annotation specs used in the confusion + // matrix, as they were at the moment of the evaluation. For Tables + // CLASSIFICATION + // + // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type], + // distinct values of the target column at the moment of the model + // evaluation are populated here. + repeated string display_name = 3; + + // Output only. Rows in the confusion matrix. The number of rows is equal to + // the size of `annotation_spec_id`. + // `row[i].example_count[j]` is the number of examples that have ground + // truth of the `annotation_spec_id[i]` and are predicted as + // `annotation_spec_id[j]` by the model being evaluated. + repeated Row row = 2; + } + + // Output only. The Area Under Precision-Recall Curve metric. Micro-averaged + // for the overall evaluation. + float au_prc = 1; + + // Output only. The Area Under Precision-Recall Curve metric based on priors. + // Micro-averaged for the overall evaluation. + // Deprecated. + float base_au_prc = 2 [deprecated = true]; + + // Output only. The Area Under Receiver Operating Characteristic curve metric. + // Micro-averaged for the overall evaluation. + float au_roc = 6; + + // Output only. The Log Loss metric. + float log_loss = 7; + + // Output only. Metrics for each confidence_threshold in + // 0.00,0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 and + // position_threshold = INT32_MAX_VALUE. + // ROC and precision-recall curves, and other aggregated metrics are derived + // from them. The confidence metrics entries may also be supplied for + // additional values of position_threshold, but from these no aggregated + // metrics are computed. + repeated ConfidenceMetricsEntry confidence_metrics_entry = 3; + + // Output only. Confusion matrix of the evaluation. + // Only set for MULTICLASS classification problems where number + // of labels is no more than 10. + // Only set for model level evaluation, not for evaluation per label. + ConfusionMatrix confusion_matrix = 4; + + // Output only. The annotation spec ids used for this evaluation. + repeated string annotation_spec_id = 5; +} diff --git a/google/cloud/automl_v1beta1/proto/column_spec.proto b/google/cloud/automl_v1beta1/proto/column_spec.proto new file mode 100644 index 00000000..03389b8a --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/column_spec.proto @@ -0,0 +1,78 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/data_stats.proto"; +import "google/cloud/automl/v1beta1/data_types.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A representation of a column in a relational table. When listing them, column specs are returned in the same order in which they were +// given on import . +// Used by: +// * Tables +message ColumnSpec { + option (google.api.resource) = { + type: "automl.googleapis.com/ColumnSpec" + pattern: "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}" + }; + + // Identifies the table's column, and its correlation with the column this + // ColumnSpec describes. + message CorrelatedColumn { + // The column_spec_id of the correlated column, which belongs to the same + // table as the in-context column. + string column_spec_id = 1; + + // Correlation between this and the in-context column. + CorrelationStats correlation_stats = 2; + } + + // Output only. The resource name of the column specs. + // Form: + // + // `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/tableSpecs/{table_spec_id}/columnSpecs/{column_spec_id}` + string name = 1; + + // The data type of elements stored in the column. + DataType data_type = 2; + + // Output only. The name of the column to show in the interface. The name can + // be up to 100 characters long and can consist only of ASCII Latin letters + // A-Z and a-z, ASCII digits 0-9, underscores(_), and forward slashes(/), and + // must start with a letter or a digit. + string display_name = 3; + + // Output only. Stats of the series of values in the column. + // This field may be stale, see the ancestor's + // Dataset.tables_dataset_metadata.stats_update_time field + // for the timestamp at which these stats were last updated. + DataStats data_stats = 4; + + // Deprecated. + repeated CorrelatedColumn top_correlated_columns = 5; + + // Used to perform consistent read-modify-write updates. If not set, a blind + // "overwrite" update happens. + string etag = 6; +} diff --git a/google/cloud/automl_v1beta1/proto/data_items.proto b/google/cloud/automl_v1beta1/proto/data_items.proto new file mode 100644 index 00000000..9b9187ad --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/data_items.proto @@ -0,0 +1,221 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/geometry.proto"; +import "google/cloud/automl/v1beta1/io.proto"; +import "google/cloud/automl/v1beta1/temporal.proto"; +import "google/cloud/automl/v1beta1/text_segment.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/struct.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A representation of an image. +// Only images up to 30MB in size are supported. +message Image { + // Input only. The data representing the image. + // For Predict calls [image_bytes][google.cloud.automl.v1beta1.Image.image_bytes] must be set, as other options are not + // currently supported by prediction API. You can read the contents of an + // uploaded image by using the [content_uri][google.cloud.automl.v1beta1.Image.content_uri] field. + oneof data { + // Image content represented as a stream of bytes. + // Note: As with all `bytes` fields, protobuffers use a pure binary + // representation, whereas JSON representations use base64. + bytes image_bytes = 1; + + // An input config specifying the content of the image. + InputConfig input_config = 6; + } + + // Output only. HTTP URI to the thumbnail image. + string thumbnail_uri = 4; +} + +// A representation of a text snippet. +message TextSnippet { + // Required. The content of the text snippet as a string. Up to 250000 + // characters long. + string content = 1; + + // Optional. The format of [content][google.cloud.automl.v1beta1.TextSnippet.content]. Currently the only two allowed + // values are "text/html" and "text/plain". If left blank, the format is + // automatically determined from the type of the uploaded [content][google.cloud.automl.v1beta1.TextSnippet.content]. + string mime_type = 2; + + // Output only. HTTP URI where you can download the content. + string content_uri = 4; +} + +// Message that describes dimension of a document. +message DocumentDimensions { + // Unit of the document dimension. + enum DocumentDimensionUnit { + // Should not be used. + DOCUMENT_DIMENSION_UNIT_UNSPECIFIED = 0; + + // Document dimension is measured in inches. + INCH = 1; + + // Document dimension is measured in centimeters. + CENTIMETER = 2; + + // Document dimension is measured in points. 72 points = 1 inch. + POINT = 3; + } + + // Unit of the dimension. + DocumentDimensionUnit unit = 1; + + // Width value of the document, works together with the unit. + float width = 2; + + // Height value of the document, works together with the unit. + float height = 3; +} + +// A structured text document e.g. a PDF. +message Document { + // Describes the layout information of a [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the document. + message Layout { + // The type of TextSegment in the context of the original document. + enum TextSegmentType { + // Should not be used. + TEXT_SEGMENT_TYPE_UNSPECIFIED = 0; + + // The text segment is a token. e.g. word. + TOKEN = 1; + + // The text segment is a paragraph. + PARAGRAPH = 2; + + // The text segment is a form field. + FORM_FIELD = 3; + + // The text segment is the name part of a form field. It will be treated + // as child of another FORM_FIELD TextSegment if its span is subspan of + // another TextSegment with type FORM_FIELD. + FORM_FIELD_NAME = 4; + + // The text segment is the text content part of a form field. It will be + // treated as child of another FORM_FIELD TextSegment if its span is + // subspan of another TextSegment with type FORM_FIELD. + FORM_FIELD_CONTENTS = 5; + + // The text segment is a whole table, including headers, and all rows. + TABLE = 6; + + // The text segment is a table's headers. It will be treated as child of + // another TABLE TextSegment if its span is subspan of another TextSegment + // with type TABLE. + TABLE_HEADER = 7; + + // The text segment is a row in table. It will be treated as child of + // another TABLE TextSegment if its span is subspan of another TextSegment + // with type TABLE. + TABLE_ROW = 8; + + // The text segment is a cell in table. It will be treated as child of + // another TABLE_ROW TextSegment if its span is subspan of another + // TextSegment with type TABLE_ROW. + TABLE_CELL = 9; + } + + // Text Segment that represents a segment in + // [document_text][google.cloud.automl.v1beta1.Document.document_text]. + TextSegment text_segment = 1; + + // Page number of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the original document, starts + // from 1. + int32 page_number = 2; + + // The position of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the page. + // Contains exactly 4 + // + // [normalized_vertices][google.cloud.automl.v1beta1.BoundingPoly.normalized_vertices] + // and they are connected by edges in the order provided, which will + // represent a rectangle parallel to the frame. The + // [NormalizedVertex-s][google.cloud.automl.v1beta1.NormalizedVertex] are + // relative to the page. + // Coordinates are based on top-left as point (0,0). + BoundingPoly bounding_poly = 3; + + // The type of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in document. + TextSegmentType text_segment_type = 4; + } + + // An input config specifying the content of the document. + DocumentInputConfig input_config = 1; + + // The plain text version of this document. + TextSnippet document_text = 2; + + // Describes the layout of the document. + // Sorted by [page_number][]. + repeated Layout layout = 3; + + // The dimensions of the page in the document. + DocumentDimensions document_dimensions = 4; + + // Number of pages in the document. + int32 page_count = 5; +} + +// A representation of a row in a relational table. +message Row { + // The resource IDs of the column specs describing the columns of the row. + // If set must contain, but possibly in a different order, all input + // feature + // + // [column_spec_ids][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] + // of the Model this row is being passed to. + // Note: The below `values` field must match order of this field, if this + // field is set. + repeated string column_spec_ids = 2; + + // Required. The values of the row cells, given in the same order as the + // column_spec_ids, or, if not set, then in the same order as input + // feature + // + // [column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] + // of the Model this row is being passed to. + repeated google.protobuf.Value values = 3; +} + +// Example data used for training or prediction. +message ExamplePayload { + // Required. Input only. The example data. + oneof payload { + // Example image. + Image image = 1; + + // Example text. + TextSnippet text_snippet = 2; + + // Example document. + Document document = 4; + + // Example relational table row. + Row row = 3; + } +} diff --git a/google/cloud/automl_v1beta1/proto/data_stats.proto b/google/cloud/automl_v1beta1/proto/data_stats.proto new file mode 100644 index 00000000..c13a5d45 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/data_stats.proto @@ -0,0 +1,166 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// The data statistics of a series of values that share the same DataType. +message DataStats { + // The data statistics specific to a DataType. + oneof stats { + // The statistics for FLOAT64 DataType. + Float64Stats float64_stats = 3; + + // The statistics for STRING DataType. + StringStats string_stats = 4; + + // The statistics for TIMESTAMP DataType. + TimestampStats timestamp_stats = 5; + + // The statistics for ARRAY DataType. + ArrayStats array_stats = 6; + + // The statistics for STRUCT DataType. + StructStats struct_stats = 7; + + // The statistics for CATEGORY DataType. + CategoryStats category_stats = 8; + } + + // The number of distinct values. + int64 distinct_value_count = 1; + + // The number of values that are null. + int64 null_value_count = 2; + + // The number of values that are valid. + int64 valid_value_count = 9; +} + +// The data statistics of a series of FLOAT64 values. +message Float64Stats { + // A bucket of a histogram. + message HistogramBucket { + // The minimum value of the bucket, inclusive. + double min = 1; + + // The maximum value of the bucket, exclusive unless max = `"Infinity"`, in + // which case it's inclusive. + double max = 2; + + // The number of data values that are in the bucket, i.e. are between + // min and max values. + int64 count = 3; + } + + // The mean of the series. + double mean = 1; + + // The standard deviation of the series. + double standard_deviation = 2; + + // Ordered from 0 to k k-quantile values of the data series of n values. + // The value at index i is, approximately, the i*n/k-th smallest value in the + // series; for i = 0 and i = k these are, respectively, the min and max + // values. + repeated double quantiles = 3; + + // Histogram buckets of the data series. Sorted by the min value of the + // bucket, ascendingly, and the number of the buckets is dynamically + // generated. The buckets are non-overlapping and completely cover whole + // FLOAT64 range with min of first bucket being `"-Infinity"`, and max of + // the last one being `"Infinity"`. + repeated HistogramBucket histogram_buckets = 4; +} + +// The data statistics of a series of STRING values. +message StringStats { + // The statistics of a unigram. + message UnigramStats { + // The unigram. + string value = 1; + + // The number of occurrences of this unigram in the series. + int64 count = 2; + } + + // The statistics of the top 20 unigrams, ordered by + // [count][google.cloud.automl.v1beta1.StringStats.UnigramStats.count]. + repeated UnigramStats top_unigram_stats = 1; +} + +// The data statistics of a series of TIMESTAMP values. +message TimestampStats { + // Stats split by a defined in context granularity. + message GranularStats { + // A map from granularity key to example count for that key. + // E.g. for hour_of_day `13` means 1pm, or for month_of_year `5` means May). + map buckets = 1; + } + + // The string key is the pre-defined granularity. Currently supported: + // hour_of_day, day_of_week, month_of_year. + // Granularities finer that the granularity of timestamp data are not + // populated (e.g. if timestamps are at day granularity, then hour_of_day + // is not populated). + map granular_stats = 1; +} + +// The data statistics of a series of ARRAY values. +message ArrayStats { + // Stats of all the values of all arrays, as if they were a single long + // series of data. The type depends on the element type of the array. + DataStats member_stats = 2; +} + +// The data statistics of a series of STRUCT values. +message StructStats { + // Map from a field name of the struct to data stats aggregated over series + // of all data in that field across all the structs. + map field_stats = 1; +} + +// The data statistics of a series of CATEGORY values. +message CategoryStats { + // The statistics of a single CATEGORY value. + message SingleCategoryStats { + // The CATEGORY value. + string value = 1; + + // The number of occurrences of this value in the series. + int64 count = 2; + } + + // The statistics of the top 20 CATEGORY values, ordered by + // + // [count][google.cloud.automl.v1beta1.CategoryStats.SingleCategoryStats.count]. + repeated SingleCategoryStats top_category_stats = 1; +} + +// A correlation statistics between two series of DataType values. The series +// may have differing DataType-s, but within a single series the DataType must +// be the same. +message CorrelationStats { + // The correlation value using the Cramer's V measure. + double cramers_v = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/data_types.proto b/google/cloud/automl_v1beta1/proto/data_types.proto new file mode 100644 index 00000000..6f77f56b --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/data_types.proto @@ -0,0 +1,105 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// `TypeCode` is used as a part of +// [DataType][google.cloud.automl.v1beta1.DataType]. +enum TypeCode { + // Not specified. Should not be used. + TYPE_CODE_UNSPECIFIED = 0; + + // Encoded as `number`, or the strings `"NaN"`, `"Infinity"`, or + // `"-Infinity"`. + FLOAT64 = 3; + + // Must be between 0AD and 9999AD. Encoded as `string` according to + // [time_format][google.cloud.automl.v1beta1.DataType.time_format], or, if + // that format is not set, then in RFC 3339 `date-time` format, where + // `time-offset` = `"Z"` (e.g. 1985-04-12T23:20:50.52Z). + TIMESTAMP = 4; + + // Encoded as `string`. + STRING = 6; + + // Encoded as `list`, where the list elements are represented according to + // + // [list_element_type][google.cloud.automl.v1beta1.DataType.list_element_type]. + ARRAY = 8; + + // Encoded as `struct`, where field values are represented according to + // [struct_type][google.cloud.automl.v1beta1.DataType.struct_type]. + STRUCT = 9; + + // Values of this type are not further understood by AutoML, + // e.g. AutoML is unable to tell the order of values (as it could with + // FLOAT64), or is unable to say if one value contains another (as it + // could with STRING). + // Encoded as `string` (bytes should be base64-encoded, as described in RFC + // 4648, section 4). + CATEGORY = 10; +} + +// Indicated the type of data that can be stored in a structured data entity +// (e.g. a table). +message DataType { + // Details of DataType-s that need additional specification. + oneof details { + // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [ARRAY][google.cloud.automl.v1beta1.TypeCode.ARRAY], + // then `list_element_type` is the type of the elements. + DataType list_element_type = 2; + + // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [STRUCT][google.cloud.automl.v1beta1.TypeCode.STRUCT], then `struct_type` + // provides type information for the struct's fields. + StructType struct_type = 3; + + // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [TIMESTAMP][google.cloud.automl.v1beta1.TypeCode.TIMESTAMP] + // then `time_format` provides the format in which that time field is + // expressed. The time_format must either be one of: + // * `UNIX_SECONDS` + // * `UNIX_MILLISECONDS` + // * `UNIX_MICROSECONDS` + // * `UNIX_NANOSECONDS` + // (for respectively number of seconds, milliseconds, microseconds and + // nanoseconds since start of the Unix epoch); + // or be written in `strftime` syntax. If time_format is not set, then the + // default format as described on the type_code is used. + string time_format = 5; + } + + // Required. The [TypeCode][google.cloud.automl.v1beta1.TypeCode] for this type. + TypeCode type_code = 1; + + // If true, this DataType can also be `NULL`. In .CSV files `NULL` value is + // expressed as an empty string. + bool nullable = 4; +} + +// `StructType` defines the DataType-s of a [STRUCT][google.cloud.automl.v1beta1.TypeCode.STRUCT] type. +message StructType { + // Unordered map of struct field names to their data types. + // Fields cannot be added or removed via Update. Their names and + // data types are still mutable. + map fields = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/dataset.proto b/google/cloud/automl_v1beta1/proto/dataset.proto new file mode 100644 index 00000000..8d1b8d93 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/dataset.proto @@ -0,0 +1,96 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/image.proto"; +import "google/cloud/automl/v1beta1/tables.proto"; +import "google/cloud/automl/v1beta1/text.proto"; +import "google/cloud/automl/v1beta1/translation.proto"; +import "google/cloud/automl/v1beta1/video.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A workspace for solving a single, particular machine learning (ML) problem. +// A workspace contains examples that may be annotated. +message Dataset { + option (google.api.resource) = { + type: "automl.googleapis.com/Dataset" + pattern: "projects/{project}/locations/{location}/datasets/{dataset}" + }; + + // Required. + // The dataset metadata that is specific to the problem type. + oneof dataset_metadata { + // Metadata for a dataset used for translation. + TranslationDatasetMetadata translation_dataset_metadata = 23; + + // Metadata for a dataset used for image classification. + ImageClassificationDatasetMetadata image_classification_dataset_metadata = 24; + + // Metadata for a dataset used for text classification. + TextClassificationDatasetMetadata text_classification_dataset_metadata = 25; + + // Metadata for a dataset used for image object detection. + ImageObjectDetectionDatasetMetadata image_object_detection_dataset_metadata = 26; + + // Metadata for a dataset used for video classification. + VideoClassificationDatasetMetadata video_classification_dataset_metadata = 31; + + // Metadata for a dataset used for video object tracking. + VideoObjectTrackingDatasetMetadata video_object_tracking_dataset_metadata = 29; + + // Metadata for a dataset used for text extraction. + TextExtractionDatasetMetadata text_extraction_dataset_metadata = 28; + + // Metadata for a dataset used for text sentiment. + TextSentimentDatasetMetadata text_sentiment_dataset_metadata = 30; + + // Metadata for a dataset used for Tables. + TablesDatasetMetadata tables_dataset_metadata = 33; + } + + // Output only. The resource name of the dataset. + // Form: `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}` + string name = 1; + + // Required. The name of the dataset to show in the interface. The name can be + // up to 32 characters long and can consist only of ASCII Latin letters A-Z + // and a-z, underscores + // (_), and ASCII digits 0-9. + string display_name = 2; + + // User-provided description of the dataset. The description can be up to + // 25000 characters long. + string description = 3; + + // Output only. The number of examples in the dataset. + int32 example_count = 21; + + // Output only. Timestamp when this dataset was created. + google.protobuf.Timestamp create_time = 14; + + // Used to perform consistent read-modify-write updates. If not set, a blind + // "overwrite" update happens. + string etag = 17; +} diff --git a/google/cloud/automl_v1beta1/proto/detection.proto b/google/cloud/automl_v1beta1/proto/detection.proto new file mode 100644 index 00000000..c5864e20 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/detection.proto @@ -0,0 +1,135 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/geometry.proto"; +import "google/protobuf/duration.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Annotation details for image object detection. +message ImageObjectDetectionAnnotation { + // Output only. The rectangle representing the object location. + BoundingPoly bounding_box = 1; + + // Output only. The confidence that this annotation is positive for the parent example, + // value in [0, 1], higher means higher positivity confidence. + float score = 2; +} + +// Annotation details for video object tracking. +message VideoObjectTrackingAnnotation { + // Optional. The instance of the object, expressed as a positive integer. Used to tell + // apart objects of the same type (i.e. AnnotationSpec) when multiple are + // present on a single example. + // NOTE: Instance ID prediction quality is not a part of model evaluation and + // is done as best effort. Especially in cases when an entity goes + // off-screen for a longer time (minutes), when it comes back it may be given + // a new instance ID. + string instance_id = 1; + + // Required. A time (frame) of a video to which this annotation pertains. + // Represented as the duration since the video's start. + google.protobuf.Duration time_offset = 2; + + // Required. The rectangle representing the object location on the frame (i.e. + // at the time_offset of the video). + BoundingPoly bounding_box = 3; + + // Output only. The confidence that this annotation is positive for the video at + // the time_offset, value in [0, 1], higher means higher positivity + // confidence. For annotations created by the user the score is 1. When + // user approves an annotation, the original float score is kept (and not + // changed to 1). + float score = 4; +} + +// Bounding box matching model metrics for a single intersection-over-union +// threshold and multiple label match confidence thresholds. +message BoundingBoxMetricsEntry { + // Metrics for a single confidence threshold. + message ConfidenceMetricsEntry { + // Output only. The confidence threshold value used to compute the metrics. + float confidence_threshold = 1; + + // Output only. Recall under the given confidence threshold. + float recall = 2; + + // Output only. Precision under the given confidence threshold. + float precision = 3; + + // Output only. The harmonic mean of recall and precision. + float f1_score = 4; + } + + // Output only. The intersection-over-union threshold value used to compute + // this metrics entry. + float iou_threshold = 1; + + // Output only. The mean average precision, most often close to au_prc. + float mean_average_precision = 2; + + // Output only. Metrics for each label-match confidence_threshold from + // 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99. Precision-recall curve is + // derived from them. + repeated ConfidenceMetricsEntry confidence_metrics_entries = 3; +} + +// Model evaluation metrics for image object detection problems. +// Evaluates prediction quality of labeled bounding boxes. +message ImageObjectDetectionEvaluationMetrics { + // Output only. The total number of bounding boxes (i.e. summed over all + // images) the ground truth used to create this evaluation had. + int32 evaluated_bounding_box_count = 1; + + // Output only. The bounding boxes match metrics for each + // Intersection-over-union threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 + // and each label confidence threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 + // pair. + repeated BoundingBoxMetricsEntry bounding_box_metrics_entries = 2; + + // Output only. The single metric for bounding boxes evaluation: + // the mean_average_precision averaged over all bounding_box_metrics_entries. + float bounding_box_mean_average_precision = 3; +} + +// Model evaluation metrics for video object tracking problems. +// Evaluates prediction quality of both labeled bounding boxes and labeled +// tracks (i.e. series of bounding boxes sharing same label and instance ID). +message VideoObjectTrackingEvaluationMetrics { + // Output only. The number of video frames used to create this evaluation. + int32 evaluated_frame_count = 1; + + // Output only. The total number of bounding boxes (i.e. summed over all + // frames) the ground truth used to create this evaluation had. + int32 evaluated_bounding_box_count = 2; + + // Output only. The bounding boxes match metrics for each + // Intersection-over-union threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 + // and each label confidence threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 + // pair. + repeated BoundingBoxMetricsEntry bounding_box_metrics_entries = 4; + + // Output only. The single metric for bounding boxes evaluation: + // the mean_average_precision averaged over all bounding_box_metrics_entries. + float bounding_box_mean_average_precision = 6; +} diff --git a/google/cloud/automl_v1beta1/proto/geometry.proto b/google/cloud/automl_v1beta1/proto/geometry.proto new file mode 100644 index 00000000..d5654aac --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/geometry.proto @@ -0,0 +1,46 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A vertex represents a 2D point in the image. +// The normalized vertex coordinates are between 0 to 1 fractions relative to +// the original plane (image, video). E.g. if the plane (e.g. whole image) would +// have size 10 x 20 then a point with normalized coordinates (0.1, 0.3) would +// be at the position (1, 6) on that plane. +message NormalizedVertex { + // Required. Horizontal coordinate. + float x = 1; + + // Required. Vertical coordinate. + float y = 2; +} + +// A bounding polygon of a detected object on a plane. +// On output both vertices and normalized_vertices are provided. +// The polygon is formed by connecting vertices in the order they are listed. +message BoundingPoly { + // Output only . The bounding polygon normalized vertices. + repeated NormalizedVertex normalized_vertices = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/image.proto b/google/cloud/automl_v1beta1/proto/image.proto new file mode 100644 index 00000000..960eaeb0 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/image.proto @@ -0,0 +1,193 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/annotation_spec.proto"; +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "ImageProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Dataset metadata that is specific to image classification. +message ImageClassificationDatasetMetadata { + // Required. Type of the classification problem. + ClassificationType classification_type = 1; +} + +// Dataset metadata specific to image object detection. +message ImageObjectDetectionDatasetMetadata { + +} + +// Model metadata for image classification. +message ImageClassificationModelMetadata { + // Optional. The ID of the `base` model. If it is specified, the new model + // will be created based on the `base` model. Otherwise, the new model will be + // created from scratch. The `base` model must be in the same + // `project` and `location` as the new model to create, and have the same + // `model_type`. + string base_model_id = 1; + + // Required. The train budget of creating this model, expressed in hours. The + // actual `train_cost` will be equal or less than this value. + int64 train_budget = 2; + + // Output only. The actual train cost of creating this model, expressed in + // hours. If this model is created from a `base` model, the train cost used + // to create the `base` model are not included. + int64 train_cost = 3; + + // Output only. The reason that this create model operation stopped, + // e.g. `BUDGET_REACHED`, `MODEL_CONVERGED`. + string stop_reason = 5; + + // Optional. Type of the model. The available values are: + // * `cloud` - Model to be used via prediction calls to AutoML API. + // This is the default value. + // * `mobile-low-latency-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. Expected to have low latency, but + // may have lower prediction quality than other models. + // * `mobile-versatile-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. + // * `mobile-high-accuracy-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. Expected to have a higher + // latency, but should also have a higher prediction quality + // than other models. + // * `mobile-core-ml-low-latency-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with Core + // ML afterwards. Expected to have low latency, but may have + // lower prediction quality than other models. + // * `mobile-core-ml-versatile-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with Core + // ML afterwards. + // * `mobile-core-ml-high-accuracy-1` - A model that, in addition to + // providing prediction via AutoML API, can also be exported + // (see [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with + // Core ML afterwards. Expected to have a higher latency, but + // should also have a higher prediction quality than other + // models. + string model_type = 7; + + // Output only. An approximate number of online prediction QPS that can + // be supported by this model per each node on which it is deployed. + double node_qps = 13; + + // Output only. The number of nodes this model is deployed on. A node is an + // abstraction of a machine resource, which can handle online prediction QPS + // as given in the node_qps field. + int64 node_count = 14; +} + +// Model metadata specific to image object detection. +message ImageObjectDetectionModelMetadata { + // Optional. Type of the model. The available values are: + // * `cloud-high-accuracy-1` - (default) A model to be used via prediction + // calls to AutoML API. Expected to have a higher latency, but + // should also have a higher prediction quality than other + // models. + // * `cloud-low-latency-1` - A model to be used via prediction + // calls to AutoML API. Expected to have low latency, but may + // have lower prediction quality than other models. + // * `mobile-low-latency-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. Expected to have low latency, but + // may have lower prediction quality than other models. + // * `mobile-versatile-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. + // * `mobile-high-accuracy-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. Expected to have a higher + // latency, but should also have a higher prediction quality + // than other models. + string model_type = 1; + + // Output only. The number of nodes this model is deployed on. A node is an + // abstraction of a machine resource, which can handle online prediction QPS + // as given in the qps_per_node field. + int64 node_count = 3; + + // Output only. An approximate number of online prediction QPS that can + // be supported by this model per each node on which it is deployed. + double node_qps = 4; + + // Output only. The reason that this create model operation stopped, + // e.g. `BUDGET_REACHED`, `MODEL_CONVERGED`. + string stop_reason = 5; + + // The train budget of creating this model, expressed in milli node + // hours i.e. 1,000 value in this field means 1 node hour. The actual + // `train_cost` will be equal or less than this value. If further model + // training ceases to provide any improvements, it will stop without using + // full budget and the stop_reason will be `MODEL_CONVERGED`. + // Note, node_hour = actual_hour * number_of_nodes_invovled. + // For model type `cloud-high-accuracy-1`(default) and `cloud-low-latency-1`, + // the train budget must be between 20,000 and 900,000 milli node hours, + // inclusive. The default value is 216, 000 which represents one day in + // wall time. + // For model type `mobile-low-latency-1`, `mobile-versatile-1`, + // `mobile-high-accuracy-1`, `mobile-core-ml-low-latency-1`, + // `mobile-core-ml-versatile-1`, `mobile-core-ml-high-accuracy-1`, the train + // budget must be between 1,000 and 100,000 milli node hours, inclusive. + // The default value is 24, 000 which represents one day in wall time. + int64 train_budget_milli_node_hours = 6; + + // Output only. The actual train cost of creating this model, expressed in + // milli node hours, i.e. 1,000 value in this field means 1 node hour. + // Guaranteed to not exceed the train budget. + int64 train_cost_milli_node_hours = 7; +} + +// Model deployment metadata specific to Image Classification. +message ImageClassificationModelDeploymentMetadata { + // Input only. The number of nodes to deploy the model on. A node is an + // abstraction of a machine resource, which can handle online prediction QPS + // as given in the model's + // + // [node_qps][google.cloud.automl.v1beta1.ImageClassificationModelMetadata.node_qps]. + // Must be between 1 and 100, inclusive on both ends. + int64 node_count = 1; +} + +// Model deployment metadata specific to Image Object Detection. +message ImageObjectDetectionModelDeploymentMetadata { + // Input only. The number of nodes to deploy the model on. A node is an + // abstraction of a machine resource, which can handle online prediction QPS + // as given in the model's + // + // [qps_per_node][google.cloud.automl.v1beta1.ImageObjectDetectionModelMetadata.qps_per_node]. + // Must be between 1 and 100, inclusive on both ends. + int64 node_count = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/io.proto b/google/cloud/automl_v1beta1/proto/io.proto new file mode 100644 index 00000000..a9979383 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/io.proto @@ -0,0 +1,1132 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Input configuration for ImportData Action. +// +// The format of input depends on dataset_metadata the Dataset into which +// the import is happening has. As input source the +// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] +// is expected, unless specified otherwise. Additionally any input .CSV file +// by itself must be 100MB or smaller, unless specified otherwise. +// If an "example" file (that is, image, video etc.) with identical content +// (even if it had different GCS_FILE_PATH) is mentioned multiple times, then +// its label, bounding boxes etc. are appended. The same file should be always +// provided with the same ML_USE and GCS_FILE_PATH, if it is not, then +// these values are nondeterministically selected from the given ones. +// +// The formats are represented in EBNF with commas being literal and with +// non-terminal symbols defined near the end of this comment. The formats are: +// +// * For Image Classification: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH,LABEL,LABEL,... +// GCS_FILE_PATH leads to image of up to 30MB in size. Supported +// extensions: .JPEG, .GIF, .PNG, .WEBP, .BMP, .TIFF, .ICO +// For MULTICLASS classification type, at most one LABEL is allowed +// per image. If an image has not yet been labeled, then it should be +// mentioned just once with no LABEL. +// Some sample rows: +// TRAIN,gs://folder/image1.jpg,daisy +// TEST,gs://folder/image2.jpg,dandelion,tulip,rose +// UNASSIGNED,gs://folder/image3.jpg,daisy +// UNASSIGNED,gs://folder/image4.jpg +// +// * For Image Object Detection: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH,(LABEL,BOUNDING_BOX | ,,,,,,,) +// GCS_FILE_PATH leads to image of up to 30MB in size. Supported +// extensions: .JPEG, .GIF, .PNG. +// Each image is assumed to be exhaustively labeled. The minimum +// allowed BOUNDING_BOX edge length is 0.01, and no more than 500 +// BOUNDING_BOX-es per image are allowed (one BOUNDING_BOX is defined +// per line). If an image has not yet been labeled, then it should be +// mentioned just once with no LABEL and the ",,,,,,," in place of the +// BOUNDING_BOX. For images which are known to not contain any +// bounding boxes, they should be labelled explictly as +// "NEGATIVE_IMAGE", followed by ",,,,,,," in place of the +// BOUNDING_BOX. +// Sample rows: +// TRAIN,gs://folder/image1.png,car,0.1,0.1,,,0.3,0.3,, +// TRAIN,gs://folder/image1.png,bike,.7,.6,,,.8,.9,, +// UNASSIGNED,gs://folder/im2.png,car,0.1,0.1,0.2,0.1,0.2,0.3,0.1,0.3 +// TEST,gs://folder/im3.png,,,,,,,,, +// TRAIN,gs://folder/im4.png,NEGATIVE_IMAGE,,,,,,,,, +// +// * For Video Classification: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH +// where ML_USE VALIDATE value should not be used. The GCS_FILE_PATH +// should lead to another .csv file which describes examples that have +// given ML_USE, using the following row format: +// GCS_FILE_PATH,(LABEL,TIME_SEGMENT_START,TIME_SEGMENT_END | ,,) +// Here GCS_FILE_PATH leads to a video of up to 50GB in size and up +// to 3h duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. +// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the +// length of the video, and end has to be after the start. Any segment +// of a video which has one or more labels on it, is considered a +// hard negative for all other labels. Any segment with no labels on +// it is considered to be unknown. If a whole video is unknown, then +// it shuold be mentioned just once with ",," in place of LABEL, +// TIME_SEGMENT_START,TIME_SEGMENT_END. +// Sample top level CSV file: +// TRAIN,gs://folder/train_videos.csv +// TEST,gs://folder/test_videos.csv +// UNASSIGNED,gs://folder/other_videos.csv +// Sample rows of a CSV file for a particular ML_USE: +// gs://folder/video1.avi,car,120,180.000021 +// gs://folder/video1.avi,bike,150,180.000021 +// gs://folder/vid2.avi,car,0,60.5 +// gs://folder/vid3.avi,,, +// +// * For Video Object Tracking: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH +// where ML_USE VALIDATE value should not be used. The GCS_FILE_PATH +// should lead to another .csv file which describes examples that have +// given ML_USE, using one of the following row format: +// GCS_FILE_PATH,LABEL,[INSTANCE_ID],TIMESTAMP,BOUNDING_BOX +// or +// GCS_FILE_PATH,,,,,,,,,, +// Here GCS_FILE_PATH leads to a video of up to 50GB in size and up +// to 3h duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. +// Providing INSTANCE_IDs can help to obtain a better model. When +// a specific labeled entity leaves the video frame, and shows up +// afterwards it is not required, albeit preferable, that the same +// INSTANCE_ID is given to it. +// TIMESTAMP must be within the length of the video, the +// BOUNDING_BOX is assumed to be drawn on the closest video's frame +// to the TIMESTAMP. Any mentioned by the TIMESTAMP frame is expected +// to be exhaustively labeled and no more than 500 BOUNDING_BOX-es per +// frame are allowed. If a whole video is unknown, then it should be +// mentioned just once with ",,,,,,,,,," in place of LABEL, +// [INSTANCE_ID],TIMESTAMP,BOUNDING_BOX. +// Sample top level CSV file: +// TRAIN,gs://folder/train_videos.csv +// TEST,gs://folder/test_videos.csv +// UNASSIGNED,gs://folder/other_videos.csv +// Seven sample rows of a CSV file for a particular ML_USE: +// gs://folder/video1.avi,car,1,12.10,0.8,0.8,0.9,0.8,0.9,0.9,0.8,0.9 +// gs://folder/video1.avi,car,1,12.90,0.4,0.8,0.5,0.8,0.5,0.9,0.4,0.9 +// gs://folder/video1.avi,car,2,12.10,.4,.2,.5,.2,.5,.3,.4,.3 +// gs://folder/video1.avi,car,2,12.90,.8,.2,,,.9,.3,, +// gs://folder/video1.avi,bike,,12.50,.45,.45,,,.55,.55,, +// gs://folder/video2.avi,car,1,0,.1,.9,,,.9,.1,, +// gs://folder/video2.avi,,,,,,,,,,, +// * For Text Extraction: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH +// GCS_FILE_PATH leads to a .JSONL (that is, JSON Lines) file which +// either imports text in-line or as documents. Any given +// .JSONL file must be 100MB or smaller. +// The in-line .JSONL file contains, per line, a proto that wraps a +// TextSnippet proto (in json representation) followed by one or more +// AnnotationPayload protos (called annotations), which have +// display_name and text_extraction detail populated. The given text +// is expected to be annotated exhaustively, for example, if you look +// for animals and text contains "dolphin" that is not labeled, then +// "dolphin" is assumed to not be an animal. Any given text snippet +// content must be 10KB or smaller, and also be UTF-8 NFC encoded +// (ASCII already is). +// The document .JSONL file contains, per line, a proto that wraps a +// Document proto. The Document proto must have either document_text +// or input_config set. In document_text case, the Document proto may +// also contain the spatial information of the document, including +// layout, document dimension and page number. In input_config case, +// only PDF documents are supported now, and each document may be up +// to 2MB large. Currently, annotations on documents cannot be +// specified at import. +// Three sample CSV rows: +// TRAIN,gs://folder/file1.jsonl +// VALIDATE,gs://folder/file2.jsonl +// TEST,gs://folder/file3.jsonl +// Sample in-line JSON Lines file for entity extraction (presented here +// with artificial line breaks, but the only actual line break is +// denoted by \n).: +// { +// "document": { +// "document_text": {"content": "dog cat"} +// "layout": [ +// { +// "text_segment": { +// "start_offset": 0, +// "end_offset": 3, +// }, +// "page_number": 1, +// "bounding_poly": { +// "normalized_vertices": [ +// {"x": 0.1, "y": 0.1}, +// {"x": 0.1, "y": 0.3}, +// {"x": 0.3, "y": 0.3}, +// {"x": 0.3, "y": 0.1}, +// ], +// }, +// "text_segment_type": TOKEN, +// }, +// { +// "text_segment": { +// "start_offset": 4, +// "end_offset": 7, +// }, +// "page_number": 1, +// "bounding_poly": { +// "normalized_vertices": [ +// {"x": 0.4, "y": 0.1}, +// {"x": 0.4, "y": 0.3}, +// {"x": 0.8, "y": 0.3}, +// {"x": 0.8, "y": 0.1}, +// ], +// }, +// "text_segment_type": TOKEN, +// } +// +// ], +// "document_dimensions": { +// "width": 8.27, +// "height": 11.69, +// "unit": INCH, +// } +// "page_count": 1, +// }, +// "annotations": [ +// { +// "display_name": "animal", +// "text_extraction": {"text_segment": {"start_offset": 0, +// "end_offset": 3}} +// }, +// { +// "display_name": "animal", +// "text_extraction": {"text_segment": {"start_offset": 4, +// "end_offset": 7}} +// } +// ], +// }\n +// { +// "text_snippet": { +// "content": "This dog is good." +// }, +// "annotations": [ +// { +// "display_name": "animal", +// "text_extraction": { +// "text_segment": {"start_offset": 5, "end_offset": 8} +// } +// } +// ] +// } +// Sample document JSON Lines file (presented here with artificial line +// breaks, but the only actual line break is denoted by \n).: +// { +// "document": { +// "input_config": { +// "gcs_source": { "input_uris": [ "gs://folder/document1.pdf" ] +// } +// } +// } +// }\n +// { +// "document": { +// "input_config": { +// "gcs_source": { "input_uris": [ "gs://folder/document2.pdf" ] +// } +// } +// } +// } +// +// * For Text Classification: +// CSV file(s) with each line in format: +// ML_USE,(TEXT_SNIPPET | GCS_FILE_PATH),LABEL,LABEL,... +// TEXT_SNIPPET and GCS_FILE_PATH are distinguished by a pattern. If +// the column content is a valid gcs file path, i.e. prefixed by +// "gs://", it will be treated as a GCS_FILE_PATH, else if the content +// is enclosed within double quotes (""), it is +// treated as a TEXT_SNIPPET. In the GCS_FILE_PATH case, the path +// must lead to a .txt file with UTF-8 encoding, for example, +// "gs://folder/content.txt", and the content in it is extracted +// as a text snippet. In TEXT_SNIPPET case, the column content +// excluding quotes is treated as to be imported text snippet. In +// both cases, the text snippet/file size must be within 128kB. +// Maximum 100 unique labels are allowed per CSV row. +// Sample rows: +// TRAIN,"They have bad food and very rude",RudeService,BadFood +// TRAIN,gs://folder/content.txt,SlowService +// TEST,"Typically always bad service there.",RudeService +// VALIDATE,"Stomach ache to go.",BadFood +// +// * For Text Sentiment: +// CSV file(s) with each line in format: +// ML_USE,(TEXT_SNIPPET | GCS_FILE_PATH),SENTIMENT +// TEXT_SNIPPET and GCS_FILE_PATH are distinguished by a pattern. If +// the column content is a valid gcs file path, that is, prefixed by +// "gs://", it is treated as a GCS_FILE_PATH, otherwise it is treated +// as a TEXT_SNIPPET. In the GCS_FILE_PATH case, the path +// must lead to a .txt file with UTF-8 encoding, for example, +// "gs://folder/content.txt", and the content in it is extracted +// as a text snippet. In TEXT_SNIPPET case, the column content itself +// is treated as to be imported text snippet. In both cases, the +// text snippet must be up to 500 characters long. +// Sample rows: +// TRAIN,"@freewrytin this is way too good for your product",2 +// TRAIN,"I need this product so bad",3 +// TEST,"Thank you for this product.",4 +// VALIDATE,gs://folder/content.txt,2 +// +// * For Tables: +// Either +// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] or +// +// [bigquery_source][google.cloud.automl.v1beta1.InputConfig.bigquery_source] +// can be used. All inputs is concatenated into a single +// +// [primary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_name] +// For gcs_source: +// CSV file(s), where the first row of the first file is the header, +// containing unique column names. If the first row of a subsequent +// file is the same as the header, then it is also treated as a +// header. All other rows contain values for the corresponding +// columns. +// Each .CSV file by itself must be 10GB or smaller, and their total +// size must be 100GB or smaller. +// First three sample rows of a CSV file: +// "Id","First Name","Last Name","Dob","Addresses" +// +// "1","John","Doe","1968-01-22","[{"status":"current","address":"123_First_Avenue","city":"Seattle","state":"WA","zip":"11111","numberOfYears":"1"},{"status":"previous","address":"456_Main_Street","city":"Portland","state":"OR","zip":"22222","numberOfYears":"5"}]" +// +// "2","Jane","Doe","1980-10-16","[{"status":"current","address":"789_Any_Avenue","city":"Albany","state":"NY","zip":"33333","numberOfYears":"2"},{"status":"previous","address":"321_Main_Street","city":"Hoboken","state":"NJ","zip":"44444","numberOfYears":"3"}]} +// For bigquery_source: +// An URI of a BigQuery table. The user data size of the BigQuery +// table must be 100GB or smaller. +// An imported table must have between 2 and 1,000 columns, inclusive, +// and between 1000 and 100,000,000 rows, inclusive. There are at most 5 +// import data running in parallel. +// Definitions: +// ML_USE = "TRAIN" | "VALIDATE" | "TEST" | "UNASSIGNED" +// Describes how the given example (file) should be used for model +// training. "UNASSIGNED" can be used when user has no preference. +// GCS_FILE_PATH = A path to file on GCS, e.g. "gs://folder/image1.png". +// LABEL = A display name of an object on an image, video etc., e.g. "dog". +// Must be up to 32 characters long and can consist only of ASCII +// Latin letters A-Z and a-z, underscores(_), and ASCII digits 0-9. +// For each label an AnnotationSpec is created which display_name +// becomes the label; AnnotationSpecs are given back in predictions. +// INSTANCE_ID = A positive integer that identifies a specific instance of a +// labeled entity on an example. Used e.g. to track two cars on +// a video while being able to tell apart which one is which. +// BOUNDING_BOX = VERTEX,VERTEX,VERTEX,VERTEX | VERTEX,,,VERTEX,, +// A rectangle parallel to the frame of the example (image, +// video). If 4 vertices are given they are connected by edges +// in the order provided, if 2 are given they are recognized +// as diagonally opposite vertices of the rectangle. +// VERTEX = COORDINATE,COORDINATE +// First coordinate is horizontal (x), the second is vertical (y). +// COORDINATE = A float in 0 to 1 range, relative to total length of +// image or video in given dimension. For fractions the +// leading non-decimal 0 can be omitted (i.e. 0.3 = .3). +// Point 0,0 is in top left. +// TIME_SEGMENT_START = TIME_OFFSET +// Expresses a beginning, inclusive, of a time segment +// within an example that has a time dimension +// (e.g. video). +// TIME_SEGMENT_END = TIME_OFFSET +// Expresses an end, exclusive, of a time segment within +// an example that has a time dimension (e.g. video). +// TIME_OFFSET = A number of seconds as measured from the start of an +// example (e.g. video). Fractions are allowed, up to a +// microsecond precision. "inf" is allowed, and it means the end +// of the example. +// TEXT_SNIPPET = A content of a text snippet, UTF-8 encoded, enclosed within +// double quotes (""). +// SENTIMENT = An integer between 0 and +// Dataset.text_sentiment_dataset_metadata.sentiment_max +// (inclusive). Describes the ordinal of the sentiment - higher +// value means a more positive sentiment. All the values are +// completely relative, i.e. neither 0 needs to mean a negative or +// neutral sentiment nor sentiment_max needs to mean a positive one +// - it is just required that 0 is the least positive sentiment +// in the data, and sentiment_max is the most positive one. +// The SENTIMENT shouldn't be confused with "score" or "magnitude" +// from the previous Natural Language Sentiment Analysis API. +// All SENTIMENT values between 0 and sentiment_max must be +// represented in the imported data. On prediction the same 0 to +// sentiment_max range will be used. The difference between +// neighboring sentiment values needs not to be uniform, e.g. 1 and +// 2 may be similar whereas the difference between 2 and 3 may be +// huge. +// +// Errors: +// If any of the provided CSV files can't be parsed or if more than certain +// percent of CSV rows cannot be processed then the operation fails and +// nothing is imported. Regardless of overall success or failure the per-row +// failures, up to a certain count cap, is listed in +// Operation.metadata.partial_failures. +// +message InputConfig { + // The source of the input. + oneof source { + // The Google Cloud Storage location for the input content. + // In ImportData, the gcs_source points to a csv with structure described in + // the comment. + GcsSource gcs_source = 1; + + // The BigQuery location for the input content. + BigQuerySource bigquery_source = 3; + } + + // Additional domain-specific parameters describing the semantic of the + // imported data, any string must be up to 25000 + // characters long. + // + // * For Tables: + // `schema_inference_version` - (integer) Required. The version of the + // algorithm that should be used for the initial inference of the + // schema (columns' DataTypes) of the table the data is being imported + // into. Allowed values: "1". + map params = 2; +} + +// Input configuration for BatchPredict Action. +// +// The format of input depends on the ML problem of the model used for +// prediction. As input source the +// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] +// is expected, unless specified otherwise. +// +// The formats are represented in EBNF with commas being literal and with +// non-terminal symbols defined near the end of this comment. The formats +// are: +// +// * For Image Classification: +// CSV file(s) with each line having just a single column: +// GCS_FILE_PATH +// which leads to image of up to 30MB in size. Supported +// extensions: .JPEG, .GIF, .PNG. This path is treated as the ID in +// the Batch predict output. +// Three sample rows: +// gs://folder/image1.jpeg +// gs://folder/image2.gif +// gs://folder/image3.png +// +// * For Image Object Detection: +// CSV file(s) with each line having just a single column: +// GCS_FILE_PATH +// which leads to image of up to 30MB in size. Supported +// extensions: .JPEG, .GIF, .PNG. This path is treated as the ID in +// the Batch predict output. +// Three sample rows: +// gs://folder/image1.jpeg +// gs://folder/image2.gif +// gs://folder/image3.png +// * For Video Classification: +// CSV file(s) with each line in format: +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END +// GCS_FILE_PATH leads to video of up to 50GB in size and up to 3h +// duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. +// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the +// length of the video, and end has to be after the start. +// Three sample rows: +// gs://folder/video1.mp4,10,40 +// gs://folder/video1.mp4,20,60 +// gs://folder/vid2.mov,0,inf +// +// * For Video Object Tracking: +// CSV file(s) with each line in format: +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END +// GCS_FILE_PATH leads to video of up to 50GB in size and up to 3h +// duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. +// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the +// length of the video, and end has to be after the start. +// Three sample rows: +// gs://folder/video1.mp4,10,240 +// gs://folder/video1.mp4,300,360 +// gs://folder/vid2.mov,0,inf +// * For Text Classification: +// CSV file(s) with each line having just a single column: +// GCS_FILE_PATH | TEXT_SNIPPET +// Any given text file can have size upto 128kB. +// Any given text snippet content must have 60,000 characters or less. +// Three sample rows: +// gs://folder/text1.txt +// "Some text content to predict" +// gs://folder/text3.pdf +// Supported file extensions: .txt, .pdf +// +// * For Text Sentiment: +// CSV file(s) with each line having just a single column: +// GCS_FILE_PATH | TEXT_SNIPPET +// Any given text file can have size upto 128kB. +// Any given text snippet content must have 500 characters or less. +// Three sample rows: +// gs://folder/text1.txt +// "Some text content to predict" +// gs://folder/text3.pdf +// Supported file extensions: .txt, .pdf +// +// * For Text Extraction +// .JSONL (i.e. JSON Lines) file(s) which either provide text in-line or +// as documents (for a single BatchPredict call only one of the these +// formats may be used). +// The in-line .JSONL file(s) contain per line a proto that +// wraps a temporary user-assigned TextSnippet ID (string up to 2000 +// characters long) called "id", a TextSnippet proto (in +// json representation) and zero or more TextFeature protos. Any given +// text snippet content must have 30,000 characters or less, and also +// be UTF-8 NFC encoded (ASCII already is). The IDs provided should be +// unique. +// The document .JSONL file(s) contain, per line, a proto that wraps a +// Document proto with input_config set. Only PDF documents are +// supported now, and each document must be up to 2MB large. +// Any given .JSONL file must be 100MB or smaller, and no more than 20 +// files may be given. +// Sample in-line JSON Lines file (presented here with artificial line +// breaks, but the only actual line break is denoted by \n): +// { +// "id": "my_first_id", +// "text_snippet": { "content": "dog car cat"}, +// "text_features": [ +// { +// "text_segment": {"start_offset": 4, "end_offset": 6}, +// "structural_type": PARAGRAPH, +// "bounding_poly": { +// "normalized_vertices": [ +// {"x": 0.1, "y": 0.1}, +// {"x": 0.1, "y": 0.3}, +// {"x": 0.3, "y": 0.3}, +// {"x": 0.3, "y": 0.1}, +// ] +// }, +// } +// ], +// }\n +// { +// "id": "2", +// "text_snippet": { +// "content": "An elaborate content", +// "mime_type": "text/plain" +// } +// } +// Sample document JSON Lines file (presented here with artificial line +// breaks, but the only actual line break is denoted by \n).: +// { +// "document": { +// "input_config": { +// "gcs_source": { "input_uris": [ "gs://folder/document1.pdf" ] +// } +// } +// } +// }\n +// { +// "document": { +// "input_config": { +// "gcs_source": { "input_uris": [ "gs://folder/document2.pdf" ] +// } +// } +// } +// } +// +// * For Tables: +// Either +// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] or +// +// [bigquery_source][google.cloud.automl.v1beta1.InputConfig.bigquery_source]. +// GCS case: +// CSV file(s), each by itself 10GB or smaller and total size must be +// 100GB or smaller, where first file must have a header containing +// column names. If the first row of a subsequent file is the same as +// the header, then it is also treated as a header. All other rows +// contain values for the corresponding columns. +// The column names must contain the model's +// +// [input_feature_column_specs'][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] +// +// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] +// (order doesn't matter). The columns corresponding to the model's +// input feature column specs must contain values compatible with the +// column spec's data types. Prediction on all the rows, i.e. the CSV +// lines, will be attempted. For FORECASTING +// +// [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: +// all columns having +// +// [TIME_SERIES_AVAILABLE_PAST_ONLY][google.cloud.automl.v1beta1.ColumnSpec.ForecastingMetadata.ColumnType] +// type will be ignored. +// First three sample rows of a CSV file: +// "First Name","Last Name","Dob","Addresses" +// +// "John","Doe","1968-01-22","[{"status":"current","address":"123_First_Avenue","city":"Seattle","state":"WA","zip":"11111","numberOfYears":"1"},{"status":"previous","address":"456_Main_Street","city":"Portland","state":"OR","zip":"22222","numberOfYears":"5"}]" +// +// "Jane","Doe","1980-10-16","[{"status":"current","address":"789_Any_Avenue","city":"Albany","state":"NY","zip":"33333","numberOfYears":"2"},{"status":"previous","address":"321_Main_Street","city":"Hoboken","state":"NJ","zip":"44444","numberOfYears":"3"}]} +// BigQuery case: +// An URI of a BigQuery table. The user data size of the BigQuery +// table must be 100GB or smaller. +// The column names must contain the model's +// +// [input_feature_column_specs'][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] +// +// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] +// (order doesn't matter). The columns corresponding to the model's +// input feature column specs must contain values compatible with the +// column spec's data types. Prediction on all the rows of the table +// will be attempted. For FORECASTING +// +// [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: +// all columns having +// +// [TIME_SERIES_AVAILABLE_PAST_ONLY][google.cloud.automl.v1beta1.ColumnSpec.ForecastingMetadata.ColumnType] +// type will be ignored. +// +// Definitions: +// GCS_FILE_PATH = A path to file on GCS, e.g. "gs://folder/video.avi". +// TEXT_SNIPPET = A content of a text snippet, UTF-8 encoded, enclosed within +// double quotes ("") +// TIME_SEGMENT_START = TIME_OFFSET +// Expresses a beginning, inclusive, of a time segment +// within an +// example that has a time dimension (e.g. video). +// TIME_SEGMENT_END = TIME_OFFSET +// Expresses an end, exclusive, of a time segment within +// an example that has a time dimension (e.g. video). +// TIME_OFFSET = A number of seconds as measured from the start of an +// example (e.g. video). Fractions are allowed, up to a +// microsecond precision. "inf" is allowed and it means the end +// of the example. +// +// Errors: +// If any of the provided CSV files can't be parsed or if more than certain +// percent of CSV rows cannot be processed then the operation fails and +// prediction does not happen. Regardless of overall success or failure the +// per-row failures, up to a certain count cap, will be listed in +// Operation.metadata.partial_failures. +message BatchPredictInputConfig { + // Required. The source of the input. + oneof source { + // The Google Cloud Storage location for the input content. + GcsSource gcs_source = 1; + + // The BigQuery location for the input content. + BigQuerySource bigquery_source = 2; + } +} + +// Input configuration of a [Document][google.cloud.automl.v1beta1.Document]. +message DocumentInputConfig { + // The Google Cloud Storage location of the document file. Only a single path + // should be given. + // Max supported size: 512MB. + // Supported extensions: .PDF. + GcsSource gcs_source = 1; +} + +// * For Translation: +// CSV file `translation.csv`, with each line in format: +// ML_USE,GCS_FILE_PATH +// GCS_FILE_PATH leads to a .TSV file which describes examples that have +// given ML_USE, using the following row format per line: +// TEXT_SNIPPET (in source language) \t TEXT_SNIPPET (in target +// language) +// +// * For Tables: +// Output depends on whether the dataset was imported from GCS or +// BigQuery. +// GCS case: +// +// [gcs_destination][google.cloud.automl.v1beta1.OutputConfig.gcs_destination] +// must be set. Exported are CSV file(s) `tables_1.csv`, +// `tables_2.csv`,...,`tables_N.csv` with each having as header line +// the table's column names, and all other lines contain values for +// the header columns. +// BigQuery case: +// +// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] +// pointing to a BigQuery project must be set. In the given project a +// new dataset will be created with name +// +// `export_data__` +// where will be made +// BigQuery-dataset-name compatible (e.g. most special characters will +// become underscores), and timestamp will be in +// YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" format. In that +// dataset a new table called `primary_table` will be created, and +// filled with precisely the same data as this obtained on import. +message OutputConfig { + // Required. The destination of the output. + oneof destination { + // The Google Cloud Storage location where the output is to be written to. + // For Image Object Detection, Text Extraction, Video Classification and + // Tables, in the given directory a new directory will be created with name: + // export_data-- where + // timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format. All export + // output will be written into that directory. + GcsDestination gcs_destination = 1; + + // The BigQuery location where the output is to be written to. + BigQueryDestination bigquery_destination = 2; + } +} + +// Output configuration for BatchPredict Action. +// +// As destination the +// +// [gcs_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.gcs_destination] +// must be set unless specified otherwise for a domain. If gcs_destination is +// set then in the given directory a new directory is created. Its name +// will be +// "prediction--", +// where timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format. The contents +// of it depends on the ML problem the predictions are made for. +// +// * For Image Classification: +// In the created directory files `image_classification_1.jsonl`, +// `image_classification_2.jsonl`,...,`image_classification_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of the successfully predicted images and annotations. +// A single image will be listed only once with all its annotations, +// and its annotations will never be split across files. +// Each .JSONL file will contain, per line, a JSON representation of a +// proto that wraps image's "ID" : "" followed by a list of +// zero or more AnnotationPayload protos (called annotations), which +// have classification detail populated. +// If prediction for any image failed (partially or completely), then an +// additional `errors_1.jsonl`, `errors_2.jsonl`,..., `errors_N.jsonl` +// files will be created (N depends on total number of failed +// predictions). These files will have a JSON representation of a proto +// that wraps the same "ID" : "" but here followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`fields. +// +// * For Image Object Detection: +// In the created directory files `image_object_detection_1.jsonl`, +// `image_object_detection_2.jsonl`,...,`image_object_detection_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of the successfully predicted images and annotations. +// Each .JSONL file will contain, per line, a JSON representation of a +// proto that wraps image's "ID" : "" followed by a list of +// zero or more AnnotationPayload protos (called annotations), which +// have image_object_detection detail populated. A single image will +// be listed only once with all its annotations, and its annotations +// will never be split across files. +// If prediction for any image failed (partially or completely), then +// additional `errors_1.jsonl`, `errors_2.jsonl`,..., `errors_N.jsonl` +// files will be created (N depends on total number of failed +// predictions). These files will have a JSON representation of a proto +// that wraps the same "ID" : "" but here followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`fields. +// * For Video Classification: +// In the created directory a video_classification.csv file, and a .JSON +// file per each video classification requested in the input (i.e. each +// line in given CSV(s)), will be created. +// +// The format of video_classification.csv is: +// +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END,JSON_FILE_NAME,STATUS +// where: +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END = matches 1 to 1 +// the prediction input lines (i.e. video_classification.csv has +// precisely the same number of lines as the prediction input had.) +// JSON_FILE_NAME = Name of .JSON file in the output directory, which +// contains prediction responses for the video time segment. +// STATUS = "OK" if prediction completed successfully, or an error code +// with message otherwise. If STATUS is not "OK" then the .JSON file +// for that line may not exist or be empty. +// +// Each .JSON file, assuming STATUS is "OK", will contain a list of +// AnnotationPayload protos in JSON format, which are the predictions +// for the video time segment the file is assigned to in the +// video_classification.csv. All AnnotationPayload protos will have +// video_classification field set, and will be sorted by +// video_classification.type field (note that the returned types are +// governed by `classifaction_types` parameter in +// [PredictService.BatchPredictRequest.params][]). +// +// * For Video Object Tracking: +// In the created directory a video_object_tracking.csv file will be +// created, and multiple files video_object_trackinng_1.json, +// video_object_trackinng_2.json,..., video_object_trackinng_N.json, +// where N is the number of requests in the input (i.e. the number of +// lines in given CSV(s)). +// +// The format of video_object_tracking.csv is: +// +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END,JSON_FILE_NAME,STATUS +// where: +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END = matches 1 to 1 +// the prediction input lines (i.e. video_object_tracking.csv has +// precisely the same number of lines as the prediction input had.) +// JSON_FILE_NAME = Name of .JSON file in the output directory, which +// contains prediction responses for the video time segment. +// STATUS = "OK" if prediction completed successfully, or an error +// code with message otherwise. If STATUS is not "OK" then the .JSON +// file for that line may not exist or be empty. +// +// Each .JSON file, assuming STATUS is "OK", will contain a list of +// AnnotationPayload protos in JSON format, which are the predictions +// for each frame of the video time segment the file is assigned to in +// video_object_tracking.csv. All AnnotationPayload protos will have +// video_object_tracking field set. +// * For Text Classification: +// In the created directory files `text_classification_1.jsonl`, +// `text_classification_2.jsonl`,...,`text_classification_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of inputs and annotations found. +// +// Each .JSONL file will contain, per line, a JSON representation of a +// proto that wraps input text snippet or input text file and a list of +// zero or more AnnotationPayload protos (called annotations), which +// have classification detail populated. A single text snippet or file +// will be listed only once with all its annotations, and its +// annotations will never be split across files. +// +// If prediction for any text snippet or file failed (partially or +// completely), then additional `errors_1.jsonl`, `errors_2.jsonl`,..., +// `errors_N.jsonl` files will be created (N depends on total number of +// failed predictions). These files will have a JSON representation of a +// proto that wraps input text snippet or input text file followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`. +// +// * For Text Sentiment: +// In the created directory files `text_sentiment_1.jsonl`, +// `text_sentiment_2.jsonl`,...,`text_sentiment_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of inputs and annotations found. +// +// Each .JSONL file will contain, per line, a JSON representation of a +// proto that wraps input text snippet or input text file and a list of +// zero or more AnnotationPayload protos (called annotations), which +// have text_sentiment detail populated. A single text snippet or file +// will be listed only once with all its annotations, and its +// annotations will never be split across files. +// +// If prediction for any text snippet or file failed (partially or +// completely), then additional `errors_1.jsonl`, `errors_2.jsonl`,..., +// `errors_N.jsonl` files will be created (N depends on total number of +// failed predictions). These files will have a JSON representation of a +// proto that wraps input text snippet or input text file followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`. +// +// * For Text Extraction: +// In the created directory files `text_extraction_1.jsonl`, +// `text_extraction_2.jsonl`,...,`text_extraction_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of inputs and annotations found. +// The contents of these .JSONL file(s) depend on whether the input +// used inline text, or documents. +// If input was inline, then each .JSONL file will contain, per line, +// a JSON representation of a proto that wraps given in request text +// snippet's "id" (if specified), followed by input text snippet, +// and a list of zero or more +// AnnotationPayload protos (called annotations), which have +// text_extraction detail populated. A single text snippet will be +// listed only once with all its annotations, and its annotations will +// never be split across files. +// If input used documents, then each .JSONL file will contain, per +// line, a JSON representation of a proto that wraps given in request +// document proto, followed by its OCR-ed representation in the form +// of a text snippet, finally followed by a list of zero or more +// AnnotationPayload protos (called annotations), which have +// text_extraction detail populated and refer, via their indices, to +// the OCR-ed text snippet. A single document (and its text snippet) +// will be listed only once with all its annotations, and its +// annotations will never be split across files. +// If prediction for any text snippet failed (partially or completely), +// then additional `errors_1.jsonl`, `errors_2.jsonl`,..., +// `errors_N.jsonl` files will be created (N depends on total number of +// failed predictions). These files will have a JSON representation of a +// proto that wraps either the "id" : "" (in case of inline) +// or the document proto (in case of document) but here followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`. +// +// * For Tables: +// Output depends on whether +// +// [gcs_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.gcs_destination] +// or +// +// [bigquery_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.bigquery_destination] +// is set (either is allowed). +// GCS case: +// In the created directory files `tables_1.csv`, `tables_2.csv`,..., +// `tables_N.csv` will be created, where N may be 1, and depends on +// the total number of the successfully predicted rows. +// For all CLASSIFICATION +// +// [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: +// Each .csv file will contain a header, listing all columns' +// +// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] +// given on input followed by M target column names in the format of +// +// "<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] +// +// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>__score" where M is the number of distinct target values, +// i.e. number of distinct values in the target column of the table +// used to train the model. Subsequent lines will contain the +// respective values of successfully predicted rows, with the last, +// i.e. the target, columns having the corresponding prediction +// [scores][google.cloud.automl.v1beta1.TablesAnnotation.score]. +// For REGRESSION and FORECASTING +// +// [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: +// Each .csv file will contain a header, listing all columns' +// [display_name-s][google.cloud.automl.v1beta1.display_name] given +// on input followed by the predicted target column with name in the +// format of +// +// "predicted_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] +// +// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>" +// Subsequent lines will contain the respective values of +// successfully predicted rows, with the last, i.e. the target, +// column having the predicted target value. +// If prediction for any rows failed, then an additional +// `errors_1.csv`, `errors_2.csv`,..., `errors_N.csv` will be +// created (N depends on total number of failed rows). These files +// will have analogous format as `tables_*.csv`, but always with a +// single target column having +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// represented as a JSON string, and containing only `code` and +// `message`. +// BigQuery case: +// +// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] +// pointing to a BigQuery project must be set. In the given project a +// new dataset will be created with name +// `prediction__` +// where will be made +// BigQuery-dataset-name compatible (e.g. most special characters will +// become underscores), and timestamp will be in +// YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" format. In the dataset +// two tables will be created, `predictions`, and `errors`. +// The `predictions` table's column names will be the input columns' +// +// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] +// followed by the target column with name in the format of +// +// "predicted_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] +// +// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>" +// The input feature columns will contain the respective values of +// successfully predicted rows, with the target column having an +// ARRAY of +// +// [AnnotationPayloads][google.cloud.automl.v1beta1.AnnotationPayload], +// represented as STRUCT-s, containing +// [TablesAnnotation][google.cloud.automl.v1beta1.TablesAnnotation]. +// The `errors` table contains rows for which the prediction has +// failed, it has analogous input columns while the target column name +// is in the format of +// +// "errors_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] +// +// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>", +// and as a value has +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// represented as a STRUCT, and containing only `code` and `message`. +message BatchPredictOutputConfig { + // Required. The destination of the output. + oneof destination { + // The Google Cloud Storage location of the directory where the output is to + // be written to. + GcsDestination gcs_destination = 1; + + // The BigQuery location where the output is to be written to. + BigQueryDestination bigquery_destination = 2; + } +} + +// Output configuration for ModelExport Action. +message ModelExportOutputConfig { + // Required. The destination of the output. + oneof destination { + // The Google Cloud Storage location where the model is to be written to. + // This location may only be set for the following model formats: + // "tflite", "edgetpu_tflite", "tf_saved_model", "tf_js", "core_ml". + // + // Under the directory given as the destination a new one with name + // "model-export--", + // where timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format, + // will be created. Inside the model and any of its supporting files + // will be written. + GcsDestination gcs_destination = 1; + + // The GCR location where model image is to be pushed to. This location + // may only be set for the following model formats: + // "docker". + // + // The model image will be created under the given URI. + GcrDestination gcr_destination = 3; + } + + // The format in which the model must be exported. The available, and default, + // formats depend on the problem and model type (if given problem and type + // combination doesn't have a format listed, it means its models are not + // exportable): + // + // * For Image Classification mobile-low-latency-1, mobile-versatile-1, + // mobile-high-accuracy-1: + // "tflite" (default), "edgetpu_tflite", "tf_saved_model", "tf_js", + // "docker". + // + // * For Image Classification mobile-core-ml-low-latency-1, + // mobile-core-ml-versatile-1, mobile-core-ml-high-accuracy-1: + // "core_ml" (default). + // Formats description: + // + // * tflite - Used for Android mobile devices. + // * edgetpu_tflite - Used for [Edge TPU](https://cloud.google.com/edge-tpu/) + // devices. + // * tf_saved_model - A tensorflow model in SavedModel format. + // * tf_js - A [TensorFlow.js](https://www.tensorflow.org/js) model that can + // be used in the browser and in Node.js using JavaScript. + // * docker - Used for Docker containers. Use the params field to customize + // the container. The container is verified to work correctly on + // ubuntu 16.04 operating system. See more at + // [containers + // + // quickstart](https: + // //cloud.google.com/vision/automl/docs/containers-gcs-quickstart) + // * core_ml - Used for iOS mobile devices. + string model_format = 4; + + // Additional model-type and format specific parameters describing the + // requirements for the to be exported model files, any string must be up to + // 25000 characters long. + // + // * For `docker` format: + // `cpu_architecture` - (string) "x86_64" (default). + // `gpu_architecture` - (string) "none" (default), "nvidia". + map params = 2; +} + +// Output configuration for ExportEvaluatedExamples Action. Note that this call +// is available only for 30 days since the moment the model was evaluated. +// The output depends on the domain, as follows (note that only examples from +// the TEST set are exported): +// +// * For Tables: +// +// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] +// pointing to a BigQuery project must be set. In the given project a +// new dataset will be created with name +// +// `export_evaluated_examples__` +// where will be made BigQuery-dataset-name +// compatible (e.g. most special characters will become underscores), +// and timestamp will be in YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" +// format. In the dataset an `evaluated_examples` table will be +// created. It will have all the same columns as the +// +// [primary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_spec_id] +// of the +// [dataset][google.cloud.automl.v1beta1.Model.dataset_id] from which +// the model was created, as they were at the moment of model's +// evaluation (this includes the target column with its ground +// truth), followed by a column called "predicted_". That +// last column will contain the model's prediction result for each +// respective row, given as ARRAY of +// [AnnotationPayloads][google.cloud.automl.v1beta1.AnnotationPayload], +// represented as STRUCT-s, containing +// [TablesAnnotation][google.cloud.automl.v1beta1.TablesAnnotation]. +message ExportEvaluatedExamplesOutputConfig { + // Required. The destination of the output. + oneof destination { + // The BigQuery location where the output is to be written to. + BigQueryDestination bigquery_destination = 2; + } +} + +// The Google Cloud Storage location for the input content. +message GcsSource { + // Required. Google Cloud Storage URIs to input files, up to 2000 characters + // long. Accepted forms: + // * Full object path, e.g. gs://bucket/directory/object.csv + repeated string input_uris = 1; +} + +// The BigQuery location for the input content. +message BigQuerySource { + // Required. BigQuery URI to a table, up to 2000 characters long. + // Accepted forms: + // * BigQuery path e.g. bq://projectId.bqDatasetId.bqTableId + string input_uri = 1; +} + +// The Google Cloud Storage location where the output is to be written to. +message GcsDestination { + // Required. Google Cloud Storage URI to output directory, up to 2000 + // characters long. + // Accepted forms: + // * Prefix path: gs://bucket/directory + // The requesting user must have write permission to the bucket. + // The directory is created if it doesn't exist. + string output_uri_prefix = 1; +} + +// The BigQuery location for the output content. +message BigQueryDestination { + // Required. BigQuery URI to a project, up to 2000 characters long. + // Accepted forms: + // * BigQuery path e.g. bq://projectId + string output_uri = 1; +} + +// The GCR location where the image must be pushed to. +message GcrDestination { + // Required. Google Contained Registry URI of the new image, up to 2000 + // characters long. See + // + // https: + // //cloud.google.com/container-registry/do + // // cs/pushing-and-pulling#pushing_an_image_to_a_registry + // Accepted forms: + // * [HOSTNAME]/[PROJECT-ID]/[IMAGE] + // * [HOSTNAME]/[PROJECT-ID]/[IMAGE]:[TAG] + // + // The requesting user must have permission to push images the project. + string output_uri = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/model.proto b/google/cloud/automl_v1beta1/proto/model.proto new file mode 100644 index 00000000..2b2e8d73 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/model.proto @@ -0,0 +1,108 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/image.proto"; +import "google/cloud/automl/v1beta1/tables.proto"; +import "google/cloud/automl/v1beta1/text.proto"; +import "google/cloud/automl/v1beta1/translation.proto"; +import "google/cloud/automl/v1beta1/video.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// API proto representing a trained machine learning model. +message Model { + option (google.api.resource) = { + type: "automl.googleapis.com/Model" + pattern: "projects/{project}/locations/{location}/models/{model}" + }; + + // Deployment state of the model. + enum DeploymentState { + // Should not be used, an un-set enum has this value by default. + DEPLOYMENT_STATE_UNSPECIFIED = 0; + + // Model is deployed. + DEPLOYED = 1; + + // Model is not deployed. + UNDEPLOYED = 2; + } + + // Required. + // The model metadata that is specific to the problem type. + // Must match the metadata type of the dataset used to train the model. + oneof model_metadata { + // Metadata for translation models. + TranslationModelMetadata translation_model_metadata = 15; + + // Metadata for image classification models. + ImageClassificationModelMetadata image_classification_model_metadata = 13; + + // Metadata for text classification models. + TextClassificationModelMetadata text_classification_model_metadata = 14; + + // Metadata for image object detection models. + ImageObjectDetectionModelMetadata image_object_detection_model_metadata = 20; + + // Metadata for video classification models. + VideoClassificationModelMetadata video_classification_model_metadata = 23; + + // Metadata for video object tracking models. + VideoObjectTrackingModelMetadata video_object_tracking_model_metadata = 21; + + // Metadata for text extraction models. + TextExtractionModelMetadata text_extraction_model_metadata = 19; + + // Metadata for Tables models. + TablesModelMetadata tables_model_metadata = 24; + + // Metadata for text sentiment models. + TextSentimentModelMetadata text_sentiment_model_metadata = 22; + } + + // Output only. Resource name of the model. + // Format: `projects/{project_id}/locations/{location_id}/models/{model_id}` + string name = 1; + + // Required. The name of the model to show in the interface. The name can be + // up to 32 characters long and can consist only of ASCII Latin letters A-Z + // and a-z, underscores + // (_), and ASCII digits 0-9. It must start with a letter. + string display_name = 2; + + // Required. The resource ID of the dataset used to create the model. The dataset must + // come from the same ancestor project and location. + string dataset_id = 3; + + // Output only. Timestamp when the model training finished and can be used for prediction. + google.protobuf.Timestamp create_time = 7; + + // Output only. Timestamp when this model was last updated. + google.protobuf.Timestamp update_time = 11; + + // Output only. Deployment state of the model. A model can only serve + // prediction requests after it gets deployed. + DeploymentState deployment_state = 8; +} diff --git a/google/cloud/automl_v1beta1/proto/model_evaluation.proto b/google/cloud/automl_v1beta1/proto/model_evaluation.proto new file mode 100644 index 00000000..d5633fcd --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/model_evaluation.proto @@ -0,0 +1,116 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/cloud/automl/v1beta1/detection.proto"; +import "google/cloud/automl/v1beta1/regression.proto"; +import "google/cloud/automl/v1beta1/tables.proto"; +import "google/cloud/automl/v1beta1/text_extraction.proto"; +import "google/cloud/automl/v1beta1/text_sentiment.proto"; +import "google/cloud/automl/v1beta1/translation.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Evaluation results of a model. +message ModelEvaluation { + option (google.api.resource) = { + type: "automl.googleapis.com/ModelEvaluation" + pattern: "projects/{project}/locations/{location}/models/{model}/modelEvaluations/{model_evaluation}" + }; + + // Output only. Problem type specific evaluation metrics. + oneof metrics { + // Model evaluation metrics for image, text, video and tables + // classification. + // Tables problem is considered a classification when the target column + // is CATEGORY DataType. + ClassificationEvaluationMetrics classification_evaluation_metrics = 8; + + // Model evaluation metrics for Tables regression. + // Tables problem is considered a regression when the target column + // has FLOAT64 DataType. + RegressionEvaluationMetrics regression_evaluation_metrics = 24; + + // Model evaluation metrics for translation. + TranslationEvaluationMetrics translation_evaluation_metrics = 9; + + // Model evaluation metrics for image object detection. + ImageObjectDetectionEvaluationMetrics image_object_detection_evaluation_metrics = 12; + + // Model evaluation metrics for video object tracking. + VideoObjectTrackingEvaluationMetrics video_object_tracking_evaluation_metrics = 14; + + // Evaluation metrics for text sentiment models. + TextSentimentEvaluationMetrics text_sentiment_evaluation_metrics = 11; + + // Evaluation metrics for text extraction models. + TextExtractionEvaluationMetrics text_extraction_evaluation_metrics = 13; + } + + // Output only. Resource name of the model evaluation. + // Format: + // + // `projects/{project_id}/locations/{location_id}/models/{model_id}/modelEvaluations/{model_evaluation_id}` + string name = 1; + + // Output only. The ID of the annotation spec that the model evaluation applies to. The + // The ID is empty for the overall model evaluation. + // For Tables annotation specs in the dataset do not exist and this ID is + // always not set, but for CLASSIFICATION + // + // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] + // the + // [display_name][google.cloud.automl.v1beta1.ModelEvaluation.display_name] + // field is used. + string annotation_spec_id = 2; + + // Output only. The value of + // [display_name][google.cloud.automl.v1beta1.AnnotationSpec.display_name] at + // the moment when the model was trained. Because this field returns a value + // at model training time, for different models trained from the same dataset, + // the values may differ, since display names could had been changed between + // the two model's trainings. + // For Tables CLASSIFICATION + // + // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] + // distinct values of the target column at the moment of the model evaluation + // are populated here. + // The display_name is empty for the overall model evaluation. + string display_name = 15; + + // Output only. Timestamp when this model evaluation was created. + google.protobuf.Timestamp create_time = 5; + + // Output only. The number of examples used for model evaluation, i.e. for + // which ground truth from time of model creation is compared against the + // predicted annotations created by the model. + // For overall ModelEvaluation (i.e. with annotation_spec_id not set) this is + // the total number of all examples used for evaluation. + // Otherwise, this is the count of examples that according to the ground + // truth were annotated by the + // + // [annotation_spec_id][google.cloud.automl.v1beta1.ModelEvaluation.annotation_spec_id]. + int32 evaluated_example_count = 6; +} diff --git a/google/cloud/automl_v1beta1/proto/operations.proto b/google/cloud/automl_v1beta1/proto/operations.proto new file mode 100644 index 00000000..cce3fedc --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/operations.proto @@ -0,0 +1,189 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/io.proto"; +import "google/cloud/automl/v1beta1/model.proto"; +import "google/cloud/automl/v1beta1/model_evaluation.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; +import "google/rpc/status.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Metadata used across all long running operations returned by AutoML API. +message OperationMetadata { + // Ouptut only. Details of specific operation. Even if this field is empty, + // the presence allows to distinguish different types of operations. + oneof details { + // Details of a Delete operation. + DeleteOperationMetadata delete_details = 8; + + // Details of a DeployModel operation. + DeployModelOperationMetadata deploy_model_details = 24; + + // Details of an UndeployModel operation. + UndeployModelOperationMetadata undeploy_model_details = 25; + + // Details of CreateModel operation. + CreateModelOperationMetadata create_model_details = 10; + + // Details of ImportData operation. + ImportDataOperationMetadata import_data_details = 15; + + // Details of BatchPredict operation. + BatchPredictOperationMetadata batch_predict_details = 16; + + // Details of ExportData operation. + ExportDataOperationMetadata export_data_details = 21; + + // Details of ExportModel operation. + ExportModelOperationMetadata export_model_details = 22; + + // Details of ExportEvaluatedExamples operation. + ExportEvaluatedExamplesOperationMetadata export_evaluated_examples_details = 26; + } + + // Output only. Progress of operation. Range: [0, 100]. + // Not used currently. + int32 progress_percent = 13; + + // Output only. Partial failures encountered. + // E.g. single files that couldn't be read. + // This field should never exceed 20 entries. + // Status details field will contain standard GCP error details. + repeated google.rpc.Status partial_failures = 2; + + // Output only. Time when the operation was created. + google.protobuf.Timestamp create_time = 3; + + // Output only. Time when the operation was updated for the last time. + google.protobuf.Timestamp update_time = 4; +} + +// Details of operations that perform deletes of any entities. +message DeleteOperationMetadata { + +} + +// Details of DeployModel operation. +message DeployModelOperationMetadata { + +} + +// Details of UndeployModel operation. +message UndeployModelOperationMetadata { + +} + +// Details of CreateModel operation. +message CreateModelOperationMetadata { + +} + +// Details of ImportData operation. +message ImportDataOperationMetadata { + +} + +// Details of ExportData operation. +message ExportDataOperationMetadata { + // Further describes this export data's output. + // Supplements + // [OutputConfig][google.cloud.automl.v1beta1.OutputConfig]. + message ExportDataOutputInfo { + // The output location to which the exported data is written. + oneof output_location { + // The full path of the Google Cloud Storage directory created, into which + // the exported data is written. + string gcs_output_directory = 1; + + // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId + // format, into which the exported data is written. + string bigquery_output_dataset = 2; + } + } + + // Output only. Information further describing this export data's output. + ExportDataOutputInfo output_info = 1; +} + +// Details of BatchPredict operation. +message BatchPredictOperationMetadata { + // Further describes this batch predict's output. + // Supplements + // + // [BatchPredictOutputConfig][google.cloud.automl.v1beta1.BatchPredictOutputConfig]. + message BatchPredictOutputInfo { + // The output location into which prediction output is written. + oneof output_location { + // The full path of the Google Cloud Storage directory created, into which + // the prediction output is written. + string gcs_output_directory = 1; + + // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId + // format, into which the prediction output is written. + string bigquery_output_dataset = 2; + } + } + + // Output only. The input config that was given upon starting this + // batch predict operation. + BatchPredictInputConfig input_config = 1; + + // Output only. Information further describing this batch predict's output. + BatchPredictOutputInfo output_info = 2; +} + +// Details of ExportModel operation. +message ExportModelOperationMetadata { + // Further describes the output of model export. + // Supplements + // + // [ModelExportOutputConfig][google.cloud.automl.v1beta1.ModelExportOutputConfig]. + message ExportModelOutputInfo { + // The full path of the Google Cloud Storage directory created, into which + // the model will be exported. + string gcs_output_directory = 1; + } + + // Output only. Information further describing the output of this model + // export. + ExportModelOutputInfo output_info = 2; +} + +// Details of EvaluatedExamples operation. +message ExportEvaluatedExamplesOperationMetadata { + // Further describes the output of the evaluated examples export. + // Supplements + // + // [ExportEvaluatedExamplesOutputConfig][google.cloud.automl.v1beta1.ExportEvaluatedExamplesOutputConfig]. + message ExportEvaluatedExamplesOutputInfo { + // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId + // format, into which the output of export evaluated examples is written. + string bigquery_output_dataset = 2; + } + + // Output only. Information further describing the output of this evaluated + // examples export. + ExportEvaluatedExamplesOutputInfo output_info = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/prediction_service.proto b/google/cloud/automl_v1beta1/proto/prediction_service.proto new file mode 100644 index 00000000..0bcf685e --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/prediction_service.proto @@ -0,0 +1,268 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/annotation_payload.proto"; +import "google/cloud/automl/v1beta1/data_items.proto"; +import "google/cloud/automl/v1beta1/io.proto"; +import "google/cloud/automl/v1beta1/operations.proto"; +import "google/longrunning/operations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "PredictionServiceProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// AutoML Prediction API. +// +// On any input that is documented to expect a string parameter in +// snake_case or kebab-case, either of those cases is accepted. +service PredictionService { + option (google.api.default_host) = "automl.googleapis.com"; + option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; + + // Perform an online prediction. The prediction result will be directly + // returned in the response. + // Available for following ML problems, and their expected request payloads: + // * Image Classification - Image in .JPEG, .GIF or .PNG format, image_bytes + // up to 30MB. + // * Image Object Detection - Image in .JPEG, .GIF or .PNG format, image_bytes + // up to 30MB. + // * Text Classification - TextSnippet, content up to 60,000 characters, + // UTF-8 encoded. + // * Text Extraction - TextSnippet, content up to 30,000 characters, + // UTF-8 NFC encoded. + // * Translation - TextSnippet, content up to 25,000 characters, UTF-8 + // encoded. + // * Tables - Row, with column values matching the columns of the model, + // up to 5MB. Not available for FORECASTING + // + // [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]. + // * Text Sentiment - TextSnippet, content up 500 characters, UTF-8 + // encoded. + rpc Predict(PredictRequest) returns (PredictResponse) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:predict" + body: "*" + }; + option (google.api.method_signature) = "name,payload,params"; + } + + // Perform a batch prediction. Unlike the online [Predict][google.cloud.automl.v1beta1.PredictionService.Predict], batch + // prediction result won't be immediately available in the response. Instead, + // a long running operation object is returned. User can poll the operation + // result via [GetOperation][google.longrunning.Operations.GetOperation] + // method. Once the operation is done, [BatchPredictResult][google.cloud.automl.v1beta1.BatchPredictResult] is returned in + // the [response][google.longrunning.Operation.response] field. + // Available for following ML problems: + // * Image Classification + // * Image Object Detection + // * Video Classification + // * Video Object Tracking * Text Extraction + // * Tables + rpc BatchPredict(BatchPredictRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:batchPredict" + body: "*" + }; + option (google.api.method_signature) = "name,input_config,output_config,params"; + option (google.longrunning.operation_info) = { + response_type: "BatchPredictResult" + metadata_type: "OperationMetadata" + }; + } +} + +// Request message for [PredictionService.Predict][google.cloud.automl.v1beta1.PredictionService.Predict]. +message PredictRequest { + // Required. Name of the model requested to serve the prediction. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // Required. Payload to perform a prediction on. The payload must match the + // problem type that the model was trained to solve. + ExamplePayload payload = 2 [(google.api.field_behavior) = REQUIRED]; + + // Additional domain-specific parameters, any string must be up to 25000 + // characters long. + // + // * For Image Classification: + // + // `score_threshold` - (float) A value from 0.0 to 1.0. When the model + // makes predictions for an image, it will only produce results that have + // at least this confidence score. The default is 0.5. + // + // * For Image Object Detection: + // `score_threshold` - (float) When Model detects objects on the image, + // it will only produce bounding boxes which have at least this + // confidence score. Value in 0 to 1 range, default is 0.5. + // `max_bounding_box_count` - (int64) No more than this number of bounding + // boxes will be returned in the response. Default is 100, the + // requested value may be limited by server. + // * For Tables: + // feature_importance - (boolean) Whether feature importance + // should be populated in the returned TablesAnnotation. + // The default is false. + map params = 3; +} + +// Response message for [PredictionService.Predict][google.cloud.automl.v1beta1.PredictionService.Predict]. +message PredictResponse { + // Prediction result. + // Translation and Text Sentiment will return precisely one payload. + repeated AnnotationPayload payload = 1; + + // The preprocessed example that AutoML actually makes prediction on. + // Empty if AutoML does not preprocess the input example. + // * For Text Extraction: + // If the input is a .pdf file, the OCR'ed text will be provided in + // [document_text][google.cloud.automl.v1beta1.Document.document_text]. + ExamplePayload preprocessed_input = 3; + + // Additional domain-specific prediction response metadata. + // + // * For Image Object Detection: + // `max_bounding_box_count` - (int64) At most that many bounding boxes per + // image could have been returned. + // + // * For Text Sentiment: + // `sentiment_score` - (float, deprecated) A value between -1 and 1, + // -1 maps to least positive sentiment, while 1 maps to the most positive + // one and the higher the score, the more positive the sentiment in the + // document is. Yet these values are relative to the training data, so + // e.g. if all data was positive then -1 will be also positive (though + // the least). + // The sentiment_score shouldn't be confused with "score" or "magnitude" + // from the previous Natural Language Sentiment Analysis API. + map metadata = 2; +} + +// Request message for [PredictionService.BatchPredict][google.cloud.automl.v1beta1.PredictionService.BatchPredict]. +message BatchPredictRequest { + // Required. Name of the model requested to serve the batch prediction. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // Required. The input configuration for batch prediction. + BatchPredictInputConfig input_config = 3 [(google.api.field_behavior) = REQUIRED]; + + // Required. The Configuration specifying where output predictions should + // be written. + BatchPredictOutputConfig output_config = 4 [(google.api.field_behavior) = REQUIRED]; + + // Required. Additional domain-specific parameters for the predictions, any string must + // be up to 25000 characters long. + // + // * For Text Classification: + // + // `score_threshold` - (float) A value from 0.0 to 1.0. When the model + // makes predictions for a text snippet, it will only produce results + // that have at least this confidence score. The default is 0.5. + // + // * For Image Classification: + // + // `score_threshold` - (float) A value from 0.0 to 1.0. When the model + // makes predictions for an image, it will only produce results that + // have at least this confidence score. The default is 0.5. + // + // * For Image Object Detection: + // + // `score_threshold` - (float) When Model detects objects on the image, + // it will only produce bounding boxes which have at least this + // confidence score. Value in 0 to 1 range, default is 0.5. + // `max_bounding_box_count` - (int64) No more than this number of bounding + // boxes will be produced per image. Default is 100, the + // requested value may be limited by server. + // + // * For Video Classification : + // + // `score_threshold` - (float) A value from 0.0 to 1.0. When the model + // makes predictions for a video, it will only produce results that + // have at least this confidence score. The default is 0.5. + // `segment_classification` - (boolean) Set to true to request + // segment-level classification. AutoML Video Intelligence returns + // labels and their confidence scores for the entire segment of the + // video that user specified in the request configuration. + // The default is "true". + // `shot_classification` - (boolean) Set to true to request shot-level + // classification. AutoML Video Intelligence determines the boundaries + // for each camera shot in the entire segment of the video that user + // specified in the request configuration. AutoML Video Intelligence + // then returns labels and their confidence scores for each detected + // shot, along with the start and end time of the shot. + // WARNING: Model evaluation is not done for this classification type, + // the quality of it depends on training data, but there are no metrics + // provided to describe that quality. The default is "false". + // `1s_interval_classification` - (boolean) Set to true to request + // classification for a video at one-second intervals. AutoML Video + // Intelligence returns labels and their confidence scores for each + // second of the entire segment of the video that user specified in the + // request configuration. + // WARNING: Model evaluation is not done for this classification + // type, the quality of it depends on training data, but there are no + // metrics provided to describe that quality. The default is + // "false". + // + // * For Tables: + // + // feature_importance - (boolean) Whether feature importance + // should be populated in the returned TablesAnnotations. The + // default is false. + // + // * For Video Object Tracking: + // + // `score_threshold` - (float) When Model detects objects on video frames, + // it will only produce bounding boxes which have at least this + // confidence score. Value in 0 to 1 range, default is 0.5. + // `max_bounding_box_count` - (int64) No more than this number of bounding + // boxes will be returned per frame. Default is 100, the requested + // value may be limited by server. + // `min_bounding_box_size` - (float) Only bounding boxes with shortest edge + // at least that long as a relative value of video frame size will be + // returned. Value in 0 to 1 range. Default is 0. + map params = 5 [(google.api.field_behavior) = REQUIRED]; +} + +// Result of the Batch Predict. This message is returned in +// [response][google.longrunning.Operation.response] of the operation returned +// by the [PredictionService.BatchPredict][google.cloud.automl.v1beta1.PredictionService.BatchPredict]. +message BatchPredictResult { + // Additional domain-specific prediction response metadata. + // + // * For Image Object Detection: + // `max_bounding_box_count` - (int64) At most that many bounding boxes per + // image could have been returned. + // + // * For Video Object Tracking: + // `max_bounding_box_count` - (int64) At most that many bounding boxes per + // frame could have been returned. + map metadata = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/ranges.proto b/google/cloud/automl_v1beta1/proto/ranges.proto new file mode 100644 index 00000000..89572bb0 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/ranges.proto @@ -0,0 +1,35 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "RangesProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A range between two double numbers. +message DoubleRange { + // Start of the range, inclusive. + double start = 1; + + // End of the range, exclusive. + double end = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/regression.proto b/google/cloud/automl_v1beta1/proto/regression.proto new file mode 100644 index 00000000..1286d3d8 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/regression.proto @@ -0,0 +1,44 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_outer_classname = "RegressionProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Metrics for regression problems. +message RegressionEvaluationMetrics { + // Output only. Root Mean Squared Error (RMSE). + float root_mean_squared_error = 1; + + // Output only. Mean Absolute Error (MAE). + float mean_absolute_error = 2; + + // Output only. Mean absolute percentage error. Only set if all ground truth + // values are are positive. + float mean_absolute_percentage_error = 3; + + // Output only. R squared. + float r_squared = 4; + + // Output only. Root mean squared log error. + float root_mean_squared_log_error = 5; +} diff --git a/google/cloud/automl_v1beta1/proto/service.proto b/google/cloud/automl_v1beta1/proto/service.proto new file mode 100644 index 00000000..a421ece1 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/service.proto @@ -0,0 +1,800 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/annotation_payload.proto"; +import "google/cloud/automl/v1beta1/annotation_spec.proto"; +import "google/cloud/automl/v1beta1/column_spec.proto"; +import "google/cloud/automl/v1beta1/dataset.proto"; +import "google/cloud/automl/v1beta1/image.proto"; +import "google/cloud/automl/v1beta1/io.proto"; +import "google/cloud/automl/v1beta1/model.proto"; +import "google/cloud/automl/v1beta1/model_evaluation.proto"; +import "google/cloud/automl/v1beta1/operations.proto"; +import "google/cloud/automl/v1beta1/table_spec.proto"; +import "google/longrunning/operations.proto"; +import "google/protobuf/field_mask.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "AutoMlProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// AutoML Server API. +// +// The resource names are assigned by the server. +// The server never reuses names that it has created after the resources with +// those names are deleted. +// +// An ID of a resource is the last element of the item's resource name. For +// `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}`, then +// the id for the item is `{dataset_id}`. +// +// Currently the only supported `location_id` is "us-central1". +// +// On any input that is documented to expect a string parameter in +// snake_case or kebab-case, either of those cases is accepted. +service AutoMl { + option (google.api.default_host) = "automl.googleapis.com"; + option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; + + // Creates a dataset. + rpc CreateDataset(CreateDatasetRequest) returns (Dataset) { + option (google.api.http) = { + post: "/v1beta1/{parent=projects/*/locations/*}/datasets" + body: "dataset" + }; + option (google.api.method_signature) = "parent,dataset"; + } + + // Gets a dataset. + rpc GetDataset(GetDatasetRequest) returns (Dataset) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/datasets/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists datasets in a project. + rpc ListDatasets(ListDatasetsRequest) returns (ListDatasetsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*}/datasets" + }; + option (google.api.method_signature) = "parent"; + } + + // Updates a dataset. + rpc UpdateDataset(UpdateDatasetRequest) returns (Dataset) { + option (google.api.http) = { + patch: "/v1beta1/{dataset.name=projects/*/locations/*/datasets/*}" + body: "dataset" + }; + option (google.api.method_signature) = "dataset"; + } + + // Deletes a dataset and all of its contents. + // Returns empty response in the + // [response][google.longrunning.Operation.response] field when it completes, + // and `delete_details` in the + // [metadata][google.longrunning.Operation.metadata] field. + rpc DeleteDataset(DeleteDatasetRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + delete: "/v1beta1/{name=projects/*/locations/*/datasets/*}" + }; + option (google.api.method_signature) = "name"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Imports data into a dataset. + // For Tables this method can only be called on an empty Dataset. + // + // For Tables: + // * A + // [schema_inference_version][google.cloud.automl.v1beta1.InputConfig.params] + // parameter must be explicitly set. + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc ImportData(ImportDataRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/datasets/*}:importData" + body: "*" + }; + option (google.api.method_signature) = "name,input_config"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Exports dataset's data to the provided output location. + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc ExportData(ExportDataRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/datasets/*}:exportData" + body: "*" + }; + option (google.api.method_signature) = "name,output_config"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Gets an annotation spec. + rpc GetAnnotationSpec(GetAnnotationSpecRequest) returns (AnnotationSpec) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/datasets/*/annotationSpecs/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Gets a table spec. + rpc GetTableSpec(GetTableSpecRequest) returns (TableSpec) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/datasets/*/tableSpecs/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists table specs in a dataset. + rpc ListTableSpecs(ListTableSpecsRequest) returns (ListTableSpecsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*/datasets/*}/tableSpecs" + }; + option (google.api.method_signature) = "parent"; + } + + // Updates a table spec. + rpc UpdateTableSpec(UpdateTableSpecRequest) returns (TableSpec) { + option (google.api.http) = { + patch: "/v1beta1/{table_spec.name=projects/*/locations/*/datasets/*/tableSpecs/*}" + body: "table_spec" + }; + option (google.api.method_signature) = "table_spec"; + } + + // Gets a column spec. + rpc GetColumnSpec(GetColumnSpecRequest) returns (ColumnSpec) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/datasets/*/tableSpecs/*/columnSpecs/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists column specs in a table spec. + rpc ListColumnSpecs(ListColumnSpecsRequest) returns (ListColumnSpecsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*/datasets/*/tableSpecs/*}/columnSpecs" + }; + option (google.api.method_signature) = "parent"; + } + + // Updates a column spec. + rpc UpdateColumnSpec(UpdateColumnSpecRequest) returns (ColumnSpec) { + option (google.api.http) = { + patch: "/v1beta1/{column_spec.name=projects/*/locations/*/datasets/*/tableSpecs/*/columnSpecs/*}" + body: "column_spec" + }; + option (google.api.method_signature) = "column_spec"; + } + + // Creates a model. + // Returns a Model in the [response][google.longrunning.Operation.response] + // field when it completes. + // When you create a model, several model evaluations are created for it: + // a global evaluation, and one evaluation for each annotation spec. + rpc CreateModel(CreateModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{parent=projects/*/locations/*}/models" + body: "model" + }; + option (google.api.method_signature) = "parent,model"; + option (google.longrunning.operation_info) = { + response_type: "Model" + metadata_type: "OperationMetadata" + }; + } + + // Gets a model. + rpc GetModel(GetModelRequest) returns (Model) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/models/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists models. + rpc ListModels(ListModelsRequest) returns (ListModelsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*}/models" + }; + option (google.api.method_signature) = "parent"; + } + + // Deletes a model. + // Returns `google.protobuf.Empty` in the + // [response][google.longrunning.Operation.response] field when it completes, + // and `delete_details` in the + // [metadata][google.longrunning.Operation.metadata] field. + rpc DeleteModel(DeleteModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + delete: "/v1beta1/{name=projects/*/locations/*/models/*}" + }; + option (google.api.method_signature) = "name"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Deploys a model. If a model is already deployed, deploying it with the + // same parameters has no effect. Deploying with different parametrs + // (as e.g. changing + // + // [node_number][google.cloud.automl.v1beta1.ImageObjectDetectionModelDeploymentMetadata.node_number]) + // will reset the deployment state without pausing the model's availability. + // + // Only applicable for Text Classification, Image Object Detection , Tables, and Image Segmentation; all other domains manage + // deployment automatically. + // + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc DeployModel(DeployModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:deploy" + body: "*" + }; + option (google.api.method_signature) = "name"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Undeploys a model. If the model is not deployed this method has no effect. + // + // Only applicable for Text Classification, Image Object Detection and Tables; + // all other domains manage deployment automatically. + // + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc UndeployModel(UndeployModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:undeploy" + body: "*" + }; + option (google.api.method_signature) = "name"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Exports a trained, "export-able", model to a user specified Google Cloud + // Storage location. A model is considered export-able if and only if it has + // an export format defined for it in + // + // [ModelExportOutputConfig][google.cloud.automl.v1beta1.ModelExportOutputConfig]. + // + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc ExportModel(ExportModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:export" + body: "*" + }; + option (google.api.method_signature) = "name,output_config"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Exports examples on which the model was evaluated (i.e. which were in the + // TEST set of the dataset the model was created from), together with their + // ground truth annotations and the annotations created (predicted) by the + // model. + // The examples, ground truth and predictions are exported in the state + // they were at the moment the model was evaluated. + // + // This export is available only for 30 days since the model evaluation is + // created. + // + // Currently only available for Tables. + // + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc ExportEvaluatedExamples(ExportEvaluatedExamplesRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:exportEvaluatedExamples" + body: "*" + }; + option (google.api.method_signature) = "name,output_config"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Gets a model evaluation. + rpc GetModelEvaluation(GetModelEvaluationRequest) returns (ModelEvaluation) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/models/*/modelEvaluations/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists model evaluations. + rpc ListModelEvaluations(ListModelEvaluationsRequest) returns (ListModelEvaluationsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*/models/*}/modelEvaluations" + }; + option (google.api.method_signature) = "parent"; + } +} + +// Request message for [AutoMl.CreateDataset][google.cloud.automl.v1beta1.AutoMl.CreateDataset]. +message CreateDatasetRequest { + // Required. The resource name of the project to create the dataset for. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "locations.googleapis.com/Location" + } + ]; + + // Required. The dataset to create. + Dataset dataset = 2 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.GetDataset][google.cloud.automl.v1beta1.AutoMl.GetDataset]. +message GetDatasetRequest { + // Required. The resource name of the dataset to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; +} + +// Request message for [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets]. +message ListDatasetsRequest { + // Required. The resource name of the project from which to list datasets. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "locations.googleapis.com/Location" + } + ]; + + // An expression for filtering the results of the request. + // + // * `dataset_metadata` - for existence of the case (e.g. + // image_classification_dataset_metadata:*). Some examples of using the filter are: + // + // * `translation_dataset_metadata:*` --> The dataset has + // translation_dataset_metadata. + string filter = 3; + + // Requested page size. Server may return fewer results than requested. + // If unspecified, server will pick a default size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return + // Typically obtained via + // [ListDatasetsResponse.next_page_token][google.cloud.automl.v1beta1.ListDatasetsResponse.next_page_token] of the previous + // [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets]. +message ListDatasetsResponse { + // The datasets read. + repeated Dataset datasets = 1; + + // A token to retrieve next page of results. + // Pass to [ListDatasetsRequest.page_token][google.cloud.automl.v1beta1.ListDatasetsRequest.page_token] to obtain that page. + string next_page_token = 2; +} + +// Request message for [AutoMl.UpdateDataset][google.cloud.automl.v1beta1.AutoMl.UpdateDataset] +message UpdateDatasetRequest { + // Required. The dataset which replaces the resource on the server. + Dataset dataset = 1 [(google.api.field_behavior) = REQUIRED]; + + // The update mask applies to the resource. + google.protobuf.FieldMask update_mask = 2; +} + +// Request message for [AutoMl.DeleteDataset][google.cloud.automl.v1beta1.AutoMl.DeleteDataset]. +message DeleteDatasetRequest { + // Required. The resource name of the dataset to delete. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; +} + +// Request message for [AutoMl.ImportData][google.cloud.automl.v1beta1.AutoMl.ImportData]. +message ImportDataRequest { + // Required. Dataset name. Dataset must already exist. All imported + // annotations and examples will be added. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; + + // Required. The desired input location and its domain specific semantics, + // if any. + InputConfig input_config = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.ExportData][google.cloud.automl.v1beta1.AutoMl.ExportData]. +message ExportDataRequest { + // Required. The resource name of the dataset. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; + + // Required. The desired output location. + OutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.GetAnnotationSpec][google.cloud.automl.v1beta1.AutoMl.GetAnnotationSpec]. +message GetAnnotationSpecRequest { + // Required. The resource name of the annotation spec to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/AnnotationSpec" + } + ]; +} + +// Request message for [AutoMl.GetTableSpec][google.cloud.automl.v1beta1.AutoMl.GetTableSpec]. +message GetTableSpecRequest { + // Required. The resource name of the table spec to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/TableSpec" + } + ]; + + // Mask specifying which fields to read. + google.protobuf.FieldMask field_mask = 2; +} + +// Request message for [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs]. +message ListTableSpecsRequest { + // Required. The resource name of the dataset to list table specs from. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; + + // Mask specifying which fields to read. + google.protobuf.FieldMask field_mask = 2; + + // Filter expression, see go/filtering. + string filter = 3; + + // Requested page size. The server can return fewer results than requested. + // If unspecified, the server will pick a default size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return. + // Typically obtained from the + // [ListTableSpecsResponse.next_page_token][google.cloud.automl.v1beta1.ListTableSpecsResponse.next_page_token] field of the previous + // [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs]. +message ListTableSpecsResponse { + // The table specs read. + repeated TableSpec table_specs = 1; + + // A token to retrieve next page of results. + // Pass to [ListTableSpecsRequest.page_token][google.cloud.automl.v1beta1.ListTableSpecsRequest.page_token] to obtain that page. + string next_page_token = 2; +} + +// Request message for [AutoMl.UpdateTableSpec][google.cloud.automl.v1beta1.AutoMl.UpdateTableSpec] +message UpdateTableSpecRequest { + // Required. The table spec which replaces the resource on the server. + TableSpec table_spec = 1 [(google.api.field_behavior) = REQUIRED]; + + // The update mask applies to the resource. + google.protobuf.FieldMask update_mask = 2; +} + +// Request message for [AutoMl.GetColumnSpec][google.cloud.automl.v1beta1.AutoMl.GetColumnSpec]. +message GetColumnSpecRequest { + // Required. The resource name of the column spec to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/ColumnSpec" + } + ]; + + // Mask specifying which fields to read. + google.protobuf.FieldMask field_mask = 2; +} + +// Request message for [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs]. +message ListColumnSpecsRequest { + // Required. The resource name of the table spec to list column specs from. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/TableSpec" + } + ]; + + // Mask specifying which fields to read. + google.protobuf.FieldMask field_mask = 2; + + // Filter expression, see go/filtering. + string filter = 3; + + // Requested page size. The server can return fewer results than requested. + // If unspecified, the server will pick a default size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return. + // Typically obtained from the + // [ListColumnSpecsResponse.next_page_token][google.cloud.automl.v1beta1.ListColumnSpecsResponse.next_page_token] field of the previous + // [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs]. +message ListColumnSpecsResponse { + // The column specs read. + repeated ColumnSpec column_specs = 1; + + // A token to retrieve next page of results. + // Pass to [ListColumnSpecsRequest.page_token][google.cloud.automl.v1beta1.ListColumnSpecsRequest.page_token] to obtain that page. + string next_page_token = 2; +} + +// Request message for [AutoMl.UpdateColumnSpec][google.cloud.automl.v1beta1.AutoMl.UpdateColumnSpec] +message UpdateColumnSpecRequest { + // Required. The column spec which replaces the resource on the server. + ColumnSpec column_spec = 1 [(google.api.field_behavior) = REQUIRED]; + + // The update mask applies to the resource. + google.protobuf.FieldMask update_mask = 2; +} + +// Request message for [AutoMl.CreateModel][google.cloud.automl.v1beta1.AutoMl.CreateModel]. +message CreateModelRequest { + // Required. Resource name of the parent project where the model is being created. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "locations.googleapis.com/Location" + } + ]; + + // Required. The model to create. + Model model = 4 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.GetModel][google.cloud.automl.v1beta1.AutoMl.GetModel]. +message GetModelRequest { + // Required. Resource name of the model. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; +} + +// Request message for [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels]. +message ListModelsRequest { + // Required. Resource name of the project, from which to list the models. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "locations.googleapis.com/Location" + } + ]; + + // An expression for filtering the results of the request. + // + // * `model_metadata` - for existence of the case (e.g. + // video_classification_model_metadata:*). + // * `dataset_id` - for = or !=. Some examples of using the filter are: + // + // * `image_classification_model_metadata:*` --> The model has + // image_classification_model_metadata. + // * `dataset_id=5` --> The model was created from a dataset with ID 5. + string filter = 3; + + // Requested page size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return + // Typically obtained via + // [ListModelsResponse.next_page_token][google.cloud.automl.v1beta1.ListModelsResponse.next_page_token] of the previous + // [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels]. +message ListModelsResponse { + // List of models in the requested page. + repeated Model model = 1; + + // A token to retrieve next page of results. + // Pass to [ListModelsRequest.page_token][google.cloud.automl.v1beta1.ListModelsRequest.page_token] to obtain that page. + string next_page_token = 2; +} + +// Request message for [AutoMl.DeleteModel][google.cloud.automl.v1beta1.AutoMl.DeleteModel]. +message DeleteModelRequest { + // Required. Resource name of the model being deleted. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; +} + +// Request message for [AutoMl.DeployModel][google.cloud.automl.v1beta1.AutoMl.DeployModel]. +message DeployModelRequest { + // The per-domain specific deployment parameters. + oneof model_deployment_metadata { + // Model deployment metadata specific to Image Object Detection. + ImageObjectDetectionModelDeploymentMetadata image_object_detection_model_deployment_metadata = 2; + + // Model deployment metadata specific to Image Classification. + ImageClassificationModelDeploymentMetadata image_classification_model_deployment_metadata = 4; + } + + // Required. Resource name of the model to deploy. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; +} + +// Request message for [AutoMl.UndeployModel][google.cloud.automl.v1beta1.AutoMl.UndeployModel]. +message UndeployModelRequest { + // Required. Resource name of the model to undeploy. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; +} + +// Request message for [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]. +// Models need to be enabled for exporting, otherwise an error code will be +// returned. +message ExportModelRequest { + // Required. The resource name of the model to export. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // Required. The desired output location and configuration. + ModelExportOutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.ExportEvaluatedExamples][google.cloud.automl.v1beta1.AutoMl.ExportEvaluatedExamples]. +message ExportEvaluatedExamplesRequest { + // Required. The resource name of the model whose evaluated examples are to + // be exported. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // Required. The desired output location and configuration. + ExportEvaluatedExamplesOutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.GetModelEvaluation][google.cloud.automl.v1beta1.AutoMl.GetModelEvaluation]. +message GetModelEvaluationRequest { + // Required. Resource name for the model evaluation. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/ModelEvaluation" + } + ]; +} + +// Request message for [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations]. +message ListModelEvaluationsRequest { + // Required. Resource name of the model to list the model evaluations for. + // If modelId is set as "-", this will list model evaluations from across all + // models of the parent location. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // An expression for filtering the results of the request. + // + // * `annotation_spec_id` - for =, != or existence. See example below for + // the last. + // + // Some examples of using the filter are: + // + // * `annotation_spec_id!=4` --> The model evaluation was done for + // annotation spec with ID different than 4. + // * `NOT annotation_spec_id:*` --> The model evaluation was done for + // aggregate of all annotation specs. + string filter = 3; + + // Requested page size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return. + // Typically obtained via + // [ListModelEvaluationsResponse.next_page_token][google.cloud.automl.v1beta1.ListModelEvaluationsResponse.next_page_token] of the previous + // [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations]. +message ListModelEvaluationsResponse { + // List of model evaluations in the requested page. + repeated ModelEvaluation model_evaluation = 1; + + // A token to retrieve next page of results. + // Pass to the [ListModelEvaluationsRequest.page_token][google.cloud.automl.v1beta1.ListModelEvaluationsRequest.page_token] field of a new + // [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations] request to obtain that page. + string next_page_token = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/table_spec.proto b/google/cloud/automl_v1beta1/proto/table_spec.proto new file mode 100644 index 00000000..bc3fc744 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/table_spec.proto @@ -0,0 +1,78 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/io.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A specification of a relational table. +// The table's schema is represented via its child column specs. It is +// pre-populated as part of ImportData by schema inference algorithm, the +// version of which is a required parameter of ImportData InputConfig. +// Note: While working with a table, at times the schema may be +// inconsistent with the data in the table (e.g. string in a FLOAT64 column). +// The consistency validation is done upon creation of a model. +// Used by: +// * Tables +message TableSpec { + option (google.api.resource) = { + type: "automl.googleapis.com/TableSpec" + pattern: "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}" + }; + + // Output only. The resource name of the table spec. + // Form: + // + // `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/tableSpecs/{table_spec_id}` + string name = 1; + + // column_spec_id of the time column. Only used if the parent dataset's + // ml_use_column_spec_id is not set. Used to split rows into TRAIN, VALIDATE + // and TEST sets such that oldest rows go to TRAIN set, newest to TEST, and + // those in between to VALIDATE. + // Required type: TIMESTAMP. + // If both this column and ml_use_column are not set, then ML use of all rows + // will be assigned by AutoML. NOTE: Updates of this field will instantly + // affect any other users concurrently working with the dataset. + string time_column_spec_id = 2; + + // Output only. The number of rows (i.e. examples) in the table. + int64 row_count = 3; + + // Output only. The number of valid rows (i.e. without values that don't match + // DataType-s of their columns). + int64 valid_row_count = 4; + + // Output only. The number of columns of the table. That is, the number of + // child ColumnSpec-s. + int64 column_count = 7; + + // Output only. Input configs via which data currently residing in the table + // had been imported. + repeated InputConfig input_configs = 5; + + // Used to perform consistent read-modify-write updates. If not set, a blind + // "overwrite" update happens. + string etag = 6; +} diff --git a/google/cloud/automl_v1beta1/proto/tables.proto b/google/cloud/automl_v1beta1/proto/tables.proto new file mode 100644 index 00000000..5327f5e7 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/tables.proto @@ -0,0 +1,292 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/cloud/automl/v1beta1/column_spec.proto"; +import "google/cloud/automl/v1beta1/data_items.proto"; +import "google/cloud/automl/v1beta1/data_stats.proto"; +import "google/cloud/automl/v1beta1/ranges.proto"; +import "google/cloud/automl/v1beta1/regression.proto"; +import "google/cloud/automl/v1beta1/temporal.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Metadata for a dataset used for AutoML Tables. +message TablesDatasetMetadata { + // Output only. The table_spec_id of the primary table of this dataset. + string primary_table_spec_id = 1; + + // column_spec_id of the primary table's column that should be used as the + // training & prediction target. + // This column must be non-nullable and have one of following data types + // (otherwise model creation will error): + // + // * CATEGORY + // + // * FLOAT64 + // + // If the type is CATEGORY , only up to + // 100 unique values may exist in that column across all rows. + // + // NOTE: Updates of this field will instantly affect any other users + // concurrently working with the dataset. + string target_column_spec_id = 2; + + // column_spec_id of the primary table's column that should be used as the + // weight column, i.e. the higher the value the more important the row will be + // during model training. + // Required type: FLOAT64. + // Allowed values: 0 to 10000, inclusive on both ends; 0 means the row is + // ignored for training. + // If not set all rows are assumed to have equal weight of 1. + // NOTE: Updates of this field will instantly affect any other users + // concurrently working with the dataset. + string weight_column_spec_id = 3; + + // column_spec_id of the primary table column which specifies a possible ML + // use of the row, i.e. the column will be used to split the rows into TRAIN, + // VALIDATE and TEST sets. + // Required type: STRING. + // This column, if set, must either have all of `TRAIN`, `VALIDATE`, `TEST` + // among its values, or only have `TEST`, `UNASSIGNED` values. In the latter + // case the rows with `UNASSIGNED` value will be assigned by AutoML. Note + // that if a given ml use distribution makes it impossible to create a "good" + // model, that call will error describing the issue. + // If both this column_spec_id and primary table's time_column_spec_id are not + // set, then all rows are treated as `UNASSIGNED`. + // NOTE: Updates of this field will instantly affect any other users + // concurrently working with the dataset. + string ml_use_column_spec_id = 4; + + // Output only. Correlations between + // + // [TablesDatasetMetadata.target_column_spec_id][google.cloud.automl.v1beta1.TablesDatasetMetadata.target_column_spec_id], + // and other columns of the + // + // [TablesDatasetMetadataprimary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_spec_id]. + // Only set if the target column is set. Mapping from other column spec id to + // its CorrelationStats with the target column. + // This field may be stale, see the stats_update_time field for + // for the timestamp at which these stats were last updated. + map target_column_correlations = 6; + + // Output only. The most recent timestamp when target_column_correlations + // field and all descendant ColumnSpec.data_stats and + // ColumnSpec.top_correlated_columns fields were last (re-)generated. Any + // changes that happened to the dataset afterwards are not reflected in these + // fields values. The regeneration happens in the background on a best effort + // basis. + google.protobuf.Timestamp stats_update_time = 7; +} + +// Model metadata specific to AutoML Tables. +message TablesModelMetadata { + // Additional optimization objective configuration. Required for + // `MAXIMIZE_PRECISION_AT_RECALL` and `MAXIMIZE_RECALL_AT_PRECISION`, + // otherwise unused. + oneof additional_optimization_objective_config { + // Required when optimization_objective is "MAXIMIZE_PRECISION_AT_RECALL". + // Must be between 0 and 1, inclusive. + float optimization_objective_recall_value = 17; + + // Required when optimization_objective is "MAXIMIZE_RECALL_AT_PRECISION". + // Must be between 0 and 1, inclusive. + float optimization_objective_precision_value = 18; + } + + // Column spec of the dataset's primary table's column the model is + // predicting. Snapshotted when model creation started. + // Only 3 fields are used: + // name - May be set on CreateModel, if it's not then the ColumnSpec + // corresponding to the current target_column_spec_id of the dataset + // the model is trained from is used. + // If neither is set, CreateModel will error. + // display_name - Output only. + // data_type - Output only. + ColumnSpec target_column_spec = 2; + + // Column specs of the dataset's primary table's columns, on which + // the model is trained and which are used as the input for predictions. + // The + // + // [target_column][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] + // as well as, according to dataset's state upon model creation, + // + // [weight_column][google.cloud.automl.v1beta1.TablesDatasetMetadata.weight_column_spec_id], + // and + // + // [ml_use_column][google.cloud.automl.v1beta1.TablesDatasetMetadata.ml_use_column_spec_id] + // must never be included here. + // + // Only 3 fields are used: + // + // * name - May be set on CreateModel, if set only the columns specified are + // used, otherwise all primary table's columns (except the ones listed + // above) are used for the training and prediction input. + // + // * display_name - Output only. + // + // * data_type - Output only. + repeated ColumnSpec input_feature_column_specs = 3; + + // Objective function the model is optimizing towards. The training process + // creates a model that maximizes/minimizes the value of the objective + // function over the validation set. + // + // The supported optimization objectives depend on the prediction type. + // If the field is not set, a default objective function is used. + // + // CLASSIFICATION_BINARY: + // "MAXIMIZE_AU_ROC" (default) - Maximize the area under the receiver + // operating characteristic (ROC) curve. + // "MINIMIZE_LOG_LOSS" - Minimize log loss. + // "MAXIMIZE_AU_PRC" - Maximize the area under the precision-recall curve. + // "MAXIMIZE_PRECISION_AT_RECALL" - Maximize precision for a specified + // recall value. + // "MAXIMIZE_RECALL_AT_PRECISION" - Maximize recall for a specified + // precision value. + // + // CLASSIFICATION_MULTI_CLASS : + // "MINIMIZE_LOG_LOSS" (default) - Minimize log loss. + // + // + // REGRESSION: + // "MINIMIZE_RMSE" (default) - Minimize root-mean-squared error (RMSE). + // "MINIMIZE_MAE" - Minimize mean-absolute error (MAE). + // "MINIMIZE_RMSLE" - Minimize root-mean-squared log error (RMSLE). + string optimization_objective = 4; + + // Output only. Auxiliary information for each of the + // input_feature_column_specs with respect to this particular model. + repeated TablesModelColumnInfo tables_model_column_info = 5; + + // Required. The train budget of creating this model, expressed in milli node + // hours i.e. 1,000 value in this field means 1 node hour. + // + // The training cost of the model will not exceed this budget. The final cost + // will be attempted to be close to the budget, though may end up being (even) + // noticeably smaller - at the backend's discretion. This especially may + // happen when further model training ceases to provide any improvements. + // + // If the budget is set to a value known to be insufficient to train a + // model for the given dataset, the training won't be attempted and + // will error. + // + // The train budget must be between 1,000 and 72,000 milli node hours, + // inclusive. + int64 train_budget_milli_node_hours = 6; + + // Output only. The actual training cost of the model, expressed in milli + // node hours, i.e. 1,000 value in this field means 1 node hour. Guaranteed + // to not exceed the train budget. + int64 train_cost_milli_node_hours = 7; + + // Use the entire training budget. This disables the early stopping feature. + // By default, the early stopping feature is enabled, which means that AutoML + // Tables might stop training before the entire training budget has been used. + bool disable_early_stopping = 12; +} + +// Contains annotation details specific to Tables. +message TablesAnnotation { + // Output only. A confidence estimate between 0.0 and 1.0, inclusive. A higher + // value means greater confidence in the returned value. + // For + // + // [target_column_spec][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] + // of FLOAT64 data type the score is not populated. + float score = 1; + + // Output only. Only populated when + // + // [target_column_spec][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] + // has FLOAT64 data type. An interval in which the exactly correct target + // value has 95% chance to be in. + DoubleRange prediction_interval = 4; + + // The predicted value of the row's + // + // [target_column][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec]. + // The value depends on the column's DataType: + // + // * CATEGORY - the predicted (with the above confidence `score`) CATEGORY + // value. + // + // * FLOAT64 - the predicted (with above `prediction_interval`) FLOAT64 value. + google.protobuf.Value value = 2; + + // Output only. Auxiliary information for each of the model's + // + // [input_feature_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] + // with respect to this particular prediction. + // If no other fields than + // + // [column_spec_name][google.cloud.automl.v1beta1.TablesModelColumnInfo.column_spec_name] + // and + // + // [column_display_name][google.cloud.automl.v1beta1.TablesModelColumnInfo.column_display_name] + // would be populated, then this whole field is not. + repeated TablesModelColumnInfo tables_model_column_info = 3; + + // Output only. Stores the prediction score for the baseline example, which + // is defined as the example with all values set to their baseline values. + // This is used as part of the Sampled Shapley explanation of the model's + // prediction. This field is populated only when feature importance is + // requested. For regression models, this holds the baseline prediction for + // the baseline example. For classification models, this holds the baseline + // prediction for the baseline example for the argmax class. + float baseline_score = 5; +} + +// An information specific to given column and Tables Model, in context +// of the Model and the predictions created by it. +message TablesModelColumnInfo { + // Output only. The name of the ColumnSpec describing the column. Not + // populated when this proto is outputted to BigQuery. + string column_spec_name = 1; + + // Output only. The display name of the column (same as the display_name of + // its ColumnSpec). + string column_display_name = 2; + + // Output only. When given as part of a Model (always populated): + // Measurement of how much model predictions correctness on the TEST data + // depend on values in this column. A value between 0 and 1, higher means + // higher influence. These values are normalized - for all input feature + // columns of a given model they add to 1. + // + // When given back by Predict (populated iff + // [feature_importance + // param][google.cloud.automl.v1beta1.PredictRequest.params] is set) or Batch + // Predict (populated iff + // [feature_importance][google.cloud.automl.v1beta1.PredictRequest.params] + // param is set): + // Measurement of how impactful for the prediction returned for the given row + // the value in this column was. Specifically, the feature importance + // specifies the marginal contribution that the feature made to the prediction + // score compared to the baseline score. These values are computed using the + // Sampled Shapley method. + float feature_importance = 3; +} diff --git a/google/cloud/automl_v1beta1/proto/temporal.proto b/google/cloud/automl_v1beta1/proto/temporal.proto new file mode 100644 index 00000000..76db8887 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/temporal.proto @@ -0,0 +1,37 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/protobuf/duration.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A time period inside of an example that has a time dimension (e.g. video). +message TimeSegment { + // Start of the time segment (inclusive), represented as the duration since + // the example start. + google.protobuf.Duration start_time_offset = 1; + + // End of the time segment (exclusive), represented as the duration since the + // example start. + google.protobuf.Duration end_time_offset = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/text.proto b/google/cloud/automl_v1beta1/proto/text.proto new file mode 100644 index 00000000..f6f33185 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/text.proto @@ -0,0 +1,65 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "TextProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Dataset metadata for classification. +message TextClassificationDatasetMetadata { + // Required. Type of the classification problem. + ClassificationType classification_type = 1; +} + +// Model metadata that is specific to text classification. +message TextClassificationModelMetadata { + // Output only. Classification type of the dataset used to train this model. + ClassificationType classification_type = 3; +} + +// Dataset metadata that is specific to text extraction +message TextExtractionDatasetMetadata { + +} + +// Model metadata that is specific to text extraction. +message TextExtractionModelMetadata { + +} + +// Dataset metadata for text sentiment. +message TextSentimentDatasetMetadata { + // Required. A sentiment is expressed as an integer ordinal, where higher value + // means a more positive sentiment. The range of sentiments that will be used + // is between 0 and sentiment_max (inclusive on both ends), and all the values + // in the range must be represented in the dataset before a model can be + // created. + // sentiment_max value must be between 1 and 10 (inclusive). + int32 sentiment_max = 1; +} + +// Model metadata that is specific to text sentiment. +message TextSentimentModelMetadata { + +} diff --git a/google/cloud/automl_v1beta1/proto/text_extraction.proto b/google/cloud/automl_v1beta1/proto/text_extraction.proto new file mode 100644 index 00000000..cfb0e0b3 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/text_extraction.proto @@ -0,0 +1,68 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/text_segment.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Annotation for identifying spans of text. +message TextExtractionAnnotation { + // Required. Text extraction annotations can either be a text segment or a + // text relation. + oneof annotation { + // An entity annotation will set this, which is the part of the original + // text to which the annotation pertains. + TextSegment text_segment = 3; + } + + // Output only. A confidence estimate between 0.0 and 1.0. A higher value + // means greater confidence in correctness of the annotation. + float score = 1; +} + +// Model evaluation metrics for text extraction problems. +message TextExtractionEvaluationMetrics { + // Metrics for a single confidence threshold. + message ConfidenceMetricsEntry { + // Output only. The confidence threshold value used to compute the metrics. + // Only annotations with score of at least this threshold are considered to + // be ones the model would return. + float confidence_threshold = 1; + + // Output only. Recall under the given confidence threshold. + float recall = 3; + + // Output only. Precision under the given confidence threshold. + float precision = 4; + + // Output only. The harmonic mean of recall and precision. + float f1_score = 5; + } + + // Output only. The Area under precision recall curve metric. + float au_prc = 1; + + // Output only. Metrics that have confidence thresholds. + // Precision-recall curve can be derived from it. + repeated ConfidenceMetricsEntry confidence_metrics_entries = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/text_segment.proto b/google/cloud/automl_v1beta1/proto/text_segment.proto new file mode 100644 index 00000000..94b17d93 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/text_segment.proto @@ -0,0 +1,41 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "TextSegmentProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A contiguous part of a text (string), assuming it has an UTF-8 NFC encoding. +message TextSegment { + // Output only. The content of the TextSegment. + string content = 3; + + // Required. Zero-based character index of the first character of the text + // segment (counting characters from the beginning of the text). + int64 start_offset = 1; + + // Required. Zero-based character index of the first character past the end of + // the text segment (counting character from the beginning of the text). + // The character at the end_offset is NOT included in the text segment. + int64 end_offset = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/text_sentiment.proto b/google/cloud/automl_v1beta1/proto/text_sentiment.proto new file mode 100644 index 00000000..5444c52b --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/text_sentiment.proto @@ -0,0 +1,80 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_outer_classname = "TextSentimentProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Contains annotation details specific to text sentiment. +message TextSentimentAnnotation { + // Output only. The sentiment with the semantic, as given to the + // [AutoMl.ImportData][google.cloud.automl.v1beta1.AutoMl.ImportData] when populating the dataset from which the model used + // for the prediction had been trained. + // The sentiment values are between 0 and + // Dataset.text_sentiment_dataset_metadata.sentiment_max (inclusive), + // with higher value meaning more positive sentiment. They are completely + // relative, i.e. 0 means least positive sentiment and sentiment_max means + // the most positive from the sentiments present in the train data. Therefore + // e.g. if train data had only negative sentiment, then sentiment_max, would + // be still negative (although least negative). + // The sentiment shouldn't be confused with "score" or "magnitude" + // from the previous Natural Language Sentiment Analysis API. + int32 sentiment = 1; +} + +// Model evaluation metrics for text sentiment problems. +message TextSentimentEvaluationMetrics { + // Output only. Precision. + float precision = 1; + + // Output only. Recall. + float recall = 2; + + // Output only. The harmonic mean of recall and precision. + float f1_score = 3; + + // Output only. Mean absolute error. Only set for the overall model + // evaluation, not for evaluation of a single annotation spec. + float mean_absolute_error = 4; + + // Output only. Mean squared error. Only set for the overall model + // evaluation, not for evaluation of a single annotation spec. + float mean_squared_error = 5; + + // Output only. Linear weighted kappa. Only set for the overall model + // evaluation, not for evaluation of a single annotation spec. + float linear_kappa = 6; + + // Output only. Quadratic weighted kappa. Only set for the overall model + // evaluation, not for evaluation of a single annotation spec. + float quadratic_kappa = 7; + + // Output only. Confusion matrix of the evaluation. + // Only set for the overall model evaluation, not for evaluation of a single + // annotation spec. + ClassificationEvaluationMetrics.ConfusionMatrix confusion_matrix = 8; + + // Output only. The annotation spec ids used for this evaluation. + // Deprecated . + repeated string annotation_spec_id = 9 [deprecated = true]; +} diff --git a/google/cloud/automl_v1beta1/proto/translation.proto b/google/cloud/automl_v1beta1/proto/translation.proto new file mode 100644 index 00000000..8585bd41 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/translation.proto @@ -0,0 +1,69 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/field_behavior.proto"; +import "google/cloud/automl/v1beta1/data_items.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "TranslationProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Dataset metadata that is specific to translation. +message TranslationDatasetMetadata { + // Required. The BCP-47 language code of the source language. + string source_language_code = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. The BCP-47 language code of the target language. + string target_language_code = 2 [(google.api.field_behavior) = REQUIRED]; +} + +// Evaluation metrics for the dataset. +message TranslationEvaluationMetrics { + // Output only. BLEU score. + double bleu_score = 1; + + // Output only. BLEU score for base model. + double base_bleu_score = 2; +} + +// Model metadata that is specific to translation. +message TranslationModelMetadata { + // The resource name of the model to use as a baseline to train the custom + // model. If unset, we use the default base model provided by Google + // Translate. Format: + // `projects/{project_id}/locations/{location_id}/models/{model_id}` + string base_model = 1; + + // Output only. Inferred from the dataset. + // The source languge (The BCP-47 language code) that is used for training. + string source_language_code = 2; + + // Output only. The target languge (The BCP-47 language code) that is used for + // training. + string target_language_code = 3; +} + +// Annotation details specific to translation. +message TranslationAnnotation { + // Output only . The translated content. + TextSnippet translated_content = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/video.proto b/google/cloud/automl_v1beta1/proto/video.proto new file mode 100644 index 00000000..268ae2a8 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/video.proto @@ -0,0 +1,48 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "VideoProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Dataset metadata specific to video classification. +// All Video Classification datasets are treated as multi label. +message VideoClassificationDatasetMetadata { + +} + +// Dataset metadata specific to video object tracking. +message VideoObjectTrackingDatasetMetadata { + +} + +// Model metadata specific to video classification. +message VideoClassificationModelMetadata { + +} + +// Model metadata specific to video object tracking. +message VideoObjectTrackingModelMetadata { + +} diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index 5c6d1f5b..de28be56 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -89,11 +89,11 @@ class AutoMlAsyncClient: dataset_path = staticmethod(AutoMlClient.dataset_path) - model_path = staticmethod(AutoMlClient.model_path) + table_spec_path = staticmethod(AutoMlClient.table_spec_path) column_spec_path = staticmethod(AutoMlClient.column_spec_path) - table_spec_path = staticmethod(AutoMlClient.table_spec_path) + model_path = staticmethod(AutoMlClient.model_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file diff --git a/noxfile.py b/noxfile.py index 9c69b3b7..709afdde 100644 --- a/noxfile.py +++ b/noxfile.py @@ -74,7 +74,6 @@ def default(session): session.install("mock", "pytest", "pytest-cov") session.install("-e", ".[pandas,storage]") - session.install("proto-plus==1.8.1") # Run py.test against the unit tests. session.run( @@ -199,36 +198,3 @@ def docfx(session): os.path.join("docs", ""), os.path.join("docs", "_build", "html", ""), ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def docfx(session): - """Build the docfx yaml files for this library.""" - - session.install("-e", ".[pandas,storage]") - session.install("sphinx<3.0.0", "alabaster", "recommonmark", "sphinx-docfx-yaml") - - shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) - session.run( - "sphinx-build", - "-T", # show full traceback on exception - "-N", # no colors - "-D", - ( - "extensions=sphinx.ext.autodoc," - "sphinx.ext.autosummary," - "docfx_yaml.extension," - "sphinx.ext.intersphinx," - "sphinx.ext.coverage," - "sphinx.ext.napoleon," - "sphinx.ext.todo," - "sphinx.ext.viewcode," - "recommonmark" - ), - "-b", - "html", - "-d", - os.path.join("docs", "_build", "doctrees", ""), - os.path.join("docs", ""), - os.path.join("docs", "_build", "html", ""), - ) diff --git a/synth.metadata b/synth.metadata index 6c3bc216..bf69619d 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,8 +3,8 @@ { "git": { "name": ".", - "remote": "git@github.com:googleapis/python-automl", - "sha": "9b218b1f1cd0caef664e51064baf5f4af07a97c1" + "remote": "https://github.com/googleapis/python-automl.git", + "sha": "8c7d54872a6e5628171f160e1a39a067d5f46563" } }, { @@ -49,5 +49,221 @@ "generator": "bazel" } } + ], + "generatedFiles": [ + ".coveragerc", + ".flake8", + ".github/CONTRIBUTING.md", + ".github/ISSUE_TEMPLATE/bug_report.md", + ".github/ISSUE_TEMPLATE/feature_request.md", + ".github/ISSUE_TEMPLATE/support_request.md", + ".github/PULL_REQUEST_TEMPLATE.md", + ".github/release-please.yml", + ".gitignore", + ".kokoro/build.sh", + ".kokoro/continuous/common.cfg", + ".kokoro/continuous/continuous.cfg", + ".kokoro/docker/docs/Dockerfile", + ".kokoro/docker/docs/fetch_gpg_keys.sh", + ".kokoro/docs/common.cfg", + ".kokoro/docs/docs-presubmit.cfg", + ".kokoro/docs/docs.cfg", + ".kokoro/presubmit/common.cfg", + ".kokoro/presubmit/presubmit.cfg", + ".kokoro/publish-docs.sh", + ".kokoro/release.sh", + ".kokoro/release/common.cfg", + ".kokoro/release/release.cfg", + ".kokoro/samples/lint/common.cfg", + ".kokoro/samples/lint/continuous.cfg", + ".kokoro/samples/lint/periodic.cfg", + ".kokoro/samples/lint/presubmit.cfg", + ".kokoro/samples/python3.6/common.cfg", + ".kokoro/samples/python3.6/continuous.cfg", + ".kokoro/samples/python3.6/periodic.cfg", + ".kokoro/samples/python3.6/presubmit.cfg", + ".kokoro/samples/python3.7/common.cfg", + ".kokoro/samples/python3.7/continuous.cfg", + ".kokoro/samples/python3.7/periodic.cfg", + ".kokoro/samples/python3.7/presubmit.cfg", + ".kokoro/samples/python3.8/common.cfg", + ".kokoro/samples/python3.8/continuous.cfg", + ".kokoro/samples/python3.8/periodic.cfg", + ".kokoro/samples/python3.8/presubmit.cfg", + ".kokoro/test-samples.sh", + ".kokoro/trampoline.sh", + ".kokoro/trampoline_v2.sh", + ".trampolinerc", + "CODE_OF_CONDUCT.md", + "CONTRIBUTING.rst", + "LICENSE", + "MANIFEST.in", + "docs/_static/custom.css", + "docs/_templates/layout.html", + "docs/automl_v1/services.rst", + "docs/automl_v1/types.rst", + "docs/automl_v1beta1/services.rst", + "docs/automl_v1beta1/types.rst", + "docs/conf.py", + "docs/multiprocessing.rst", + "google/cloud/automl/__init__.py", + "google/cloud/automl/py.typed", + "google/cloud/automl_v1/__init__.py", + "google/cloud/automl_v1/proto/annotation_payload.proto", + "google/cloud/automl_v1/proto/annotation_spec.proto", + "google/cloud/automl_v1/proto/classification.proto", + "google/cloud/automl_v1/proto/data_items.proto", + "google/cloud/automl_v1/proto/dataset.proto", + "google/cloud/automl_v1/proto/detection.proto", + "google/cloud/automl_v1/proto/geometry.proto", + "google/cloud/automl_v1/proto/image.proto", + "google/cloud/automl_v1/proto/io.proto", + "google/cloud/automl_v1/proto/model.proto", + "google/cloud/automl_v1/proto/model_evaluation.proto", + "google/cloud/automl_v1/proto/operations.proto", + "google/cloud/automl_v1/proto/prediction_service.proto", + "google/cloud/automl_v1/proto/service.proto", + "google/cloud/automl_v1/proto/text.proto", + "google/cloud/automl_v1/proto/text_extraction.proto", + "google/cloud/automl_v1/proto/text_segment.proto", + "google/cloud/automl_v1/proto/text_sentiment.proto", + "google/cloud/automl_v1/proto/translation.proto", + "google/cloud/automl_v1/py.typed", + "google/cloud/automl_v1/services/__init__.py", + "google/cloud/automl_v1/services/auto_ml/__init__.py", + "google/cloud/automl_v1/services/auto_ml/async_client.py", + "google/cloud/automl_v1/services/auto_ml/client.py", + "google/cloud/automl_v1/services/auto_ml/pagers.py", + "google/cloud/automl_v1/services/auto_ml/transports/__init__.py", + "google/cloud/automl_v1/services/auto_ml/transports/base.py", + "google/cloud/automl_v1/services/auto_ml/transports/grpc.py", + "google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py", + "google/cloud/automl_v1/services/prediction_service/__init__.py", + "google/cloud/automl_v1/services/prediction_service/async_client.py", + "google/cloud/automl_v1/services/prediction_service/client.py", + "google/cloud/automl_v1/services/prediction_service/transports/__init__.py", + "google/cloud/automl_v1/services/prediction_service/transports/base.py", + "google/cloud/automl_v1/services/prediction_service/transports/grpc.py", + "google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py", + "google/cloud/automl_v1/types/__init__.py", + "google/cloud/automl_v1/types/annotation_payload.py", + "google/cloud/automl_v1/types/annotation_spec.py", + "google/cloud/automl_v1/types/classification.py", + "google/cloud/automl_v1/types/data_items.py", + "google/cloud/automl_v1/types/dataset.py", + "google/cloud/automl_v1/types/detection.py", + "google/cloud/automl_v1/types/geometry.py", + "google/cloud/automl_v1/types/image.py", + "google/cloud/automl_v1/types/io.py", + "google/cloud/automl_v1/types/model.py", + "google/cloud/automl_v1/types/model_evaluation.py", + "google/cloud/automl_v1/types/operations.py", + "google/cloud/automl_v1/types/prediction_service.py", + "google/cloud/automl_v1/types/service.py", + "google/cloud/automl_v1/types/text.py", + "google/cloud/automl_v1/types/text_extraction.py", + "google/cloud/automl_v1/types/text_segment.py", + "google/cloud/automl_v1/types/text_sentiment.py", + "google/cloud/automl_v1/types/translation.py", + "google/cloud/automl_v1beta1/__init__.py", + "google/cloud/automl_v1beta1/proto/annotation_payload.proto", + "google/cloud/automl_v1beta1/proto/annotation_spec.proto", + "google/cloud/automl_v1beta1/proto/classification.proto", + "google/cloud/automl_v1beta1/proto/column_spec.proto", + "google/cloud/automl_v1beta1/proto/data_items.proto", + "google/cloud/automl_v1beta1/proto/data_stats.proto", + "google/cloud/automl_v1beta1/proto/data_types.proto", + "google/cloud/automl_v1beta1/proto/dataset.proto", + "google/cloud/automl_v1beta1/proto/detection.proto", + "google/cloud/automl_v1beta1/proto/geometry.proto", + "google/cloud/automl_v1beta1/proto/image.proto", + "google/cloud/automl_v1beta1/proto/io.proto", + "google/cloud/automl_v1beta1/proto/model.proto", + "google/cloud/automl_v1beta1/proto/model_evaluation.proto", + "google/cloud/automl_v1beta1/proto/operations.proto", + "google/cloud/automl_v1beta1/proto/prediction_service.proto", + "google/cloud/automl_v1beta1/proto/ranges.proto", + "google/cloud/automl_v1beta1/proto/regression.proto", + "google/cloud/automl_v1beta1/proto/service.proto", + "google/cloud/automl_v1beta1/proto/table_spec.proto", + "google/cloud/automl_v1beta1/proto/tables.proto", + "google/cloud/automl_v1beta1/proto/temporal.proto", + "google/cloud/automl_v1beta1/proto/text.proto", + "google/cloud/automl_v1beta1/proto/text_extraction.proto", + "google/cloud/automl_v1beta1/proto/text_segment.proto", + "google/cloud/automl_v1beta1/proto/text_sentiment.proto", + "google/cloud/automl_v1beta1/proto/translation.proto", + "google/cloud/automl_v1beta1/proto/video.proto", + "google/cloud/automl_v1beta1/py.typed", + "google/cloud/automl_v1beta1/services/__init__.py", + "google/cloud/automl_v1beta1/services/auto_ml/__init__.py", + "google/cloud/automl_v1beta1/services/auto_ml/async_client.py", + "google/cloud/automl_v1beta1/services/auto_ml/client.py", + "google/cloud/automl_v1beta1/services/auto_ml/pagers.py", + "google/cloud/automl_v1beta1/services/auto_ml/transports/__init__.py", + "google/cloud/automl_v1beta1/services/auto_ml/transports/base.py", + "google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py", + "google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py", + "google/cloud/automl_v1beta1/services/prediction_service/__init__.py", + "google/cloud/automl_v1beta1/services/prediction_service/async_client.py", + "google/cloud/automl_v1beta1/services/prediction_service/client.py", + "google/cloud/automl_v1beta1/services/prediction_service/transports/__init__.py", + "google/cloud/automl_v1beta1/services/prediction_service/transports/base.py", + "google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py", + "google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py", + "google/cloud/automl_v1beta1/types/__init__.py", + "google/cloud/automl_v1beta1/types/annotation_payload.py", + "google/cloud/automl_v1beta1/types/annotation_spec.py", + "google/cloud/automl_v1beta1/types/classification.py", + "google/cloud/automl_v1beta1/types/column_spec.py", + "google/cloud/automl_v1beta1/types/data_items.py", + "google/cloud/automl_v1beta1/types/data_stats.py", + "google/cloud/automl_v1beta1/types/data_types.py", + "google/cloud/automl_v1beta1/types/dataset.py", + "google/cloud/automl_v1beta1/types/detection.py", + "google/cloud/automl_v1beta1/types/geometry.py", + "google/cloud/automl_v1beta1/types/image.py", + "google/cloud/automl_v1beta1/types/io.py", + "google/cloud/automl_v1beta1/types/model.py", + "google/cloud/automl_v1beta1/types/model_evaluation.py", + "google/cloud/automl_v1beta1/types/operations.py", + "google/cloud/automl_v1beta1/types/prediction_service.py", + "google/cloud/automl_v1beta1/types/ranges.py", + "google/cloud/automl_v1beta1/types/regression.py", + "google/cloud/automl_v1beta1/types/service.py", + "google/cloud/automl_v1beta1/types/table_spec.py", + "google/cloud/automl_v1beta1/types/tables.py", + "google/cloud/automl_v1beta1/types/temporal.py", + "google/cloud/automl_v1beta1/types/text.py", + "google/cloud/automl_v1beta1/types/text_extraction.py", + "google/cloud/automl_v1beta1/types/text_segment.py", + "google/cloud/automl_v1beta1/types/text_sentiment.py", + "google/cloud/automl_v1beta1/types/translation.py", + "google/cloud/automl_v1beta1/types/video.py", + "mypy.ini", + "noxfile.py", + "renovate.json", + "samples/AUTHORING_GUIDE.md", + "samples/CONTRIBUTING.md", + "samples/beta/noxfile.py", + "samples/snippets/noxfile.py", + "samples/tables/noxfile.py", + "scripts/decrypt-secrets.sh", + "scripts/fixup_automl_v1_keywords.py", + "scripts/fixup_automl_v1beta1_keywords.py", + "scripts/readme-gen/readme_gen.py", + "scripts/readme-gen/templates/README.tmpl.rst", + "scripts/readme-gen/templates/auth.tmpl.rst", + "scripts/readme-gen/templates/auth_api_key.tmpl.rst", + "scripts/readme-gen/templates/install_deps.tmpl.rst", + "scripts/readme-gen/templates/install_portaudio.tmpl.rst", + "setup.cfg", + "testing/.gitignore", + "tests/unit/gapic/automl_v1/__init__.py", + "tests/unit/gapic/automl_v1/test_auto_ml.py", + "tests/unit/gapic/automl_v1/test_prediction_service.py", + "tests/unit/gapic/automl_v1beta1/__init__.py", + "tests/unit/gapic/automl_v1beta1/test_auto_ml.py", + "tests/unit/gapic/automl_v1beta1/test_prediction_service.py" ] } \ No newline at end of file diff --git a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py index 2464c824..c6b7d4b3 100644 --- a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py @@ -6514,28 +6514,30 @@ def test_parse_dataset_path(): assert expected == actual -def test_model_path(): +def test_table_spec_path(): project = "squid" location = "clam" - model = "whelk" + dataset = "whelk" + table_spec = "octopus" - expected = "projects/{project}/locations/{location}/models/{model}".format( - project=project, location=location, model=model, + expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( + project=project, location=location, dataset=dataset, table_spec=table_spec, ) - actual = AutoMlClient.model_path(project, location, model) + actual = AutoMlClient.table_spec_path(project, location, dataset, table_spec) assert expected == actual -def test_parse_model_path(): +def test_parse_table_spec_path(): expected = { - "project": "octopus", - "location": "oyster", - "model": "nudibranch", + "project": "oyster", + "location": "nudibranch", + "dataset": "cuttlefish", + "table_spec": "mussel", } - path = AutoMlClient.model_path(**expected) + path = AutoMlClient.table_spec_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_model_path(path) + actual = AutoMlClient.parse_table_spec_path(path) assert expected == actual @@ -6574,30 +6576,28 @@ def test_parse_column_spec_path(): assert expected == actual -def test_table_spec_path(): +def test_model_path(): project = "squid" location = "clam" - dataset = "whelk" - table_spec = "octopus" + model = "whelk" - expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( - project=project, location=location, dataset=dataset, table_spec=table_spec, + expected = "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, ) - actual = AutoMlClient.table_spec_path(project, location, dataset, table_spec) + actual = AutoMlClient.model_path(project, location, model) assert expected == actual -def test_parse_table_spec_path(): +def test_parse_model_path(): expected = { - "project": "oyster", - "location": "nudibranch", - "dataset": "cuttlefish", - "table_spec": "mussel", + "project": "octopus", + "location": "oyster", + "model": "nudibranch", } - path = AutoMlClient.table_spec_path(**expected) + path = AutoMlClient.model_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_table_spec_path(path) + actual = AutoMlClient.parse_model_path(path) assert expected == actual From f9cd96ec5537baa9d549b91f7effa66635a60bd5 Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:46:27 -0700 Subject: [PATCH 02/25] chore(java_templates): stop running pmd/spotbugs checks for samples This was creating too much noise. We will revisit with other options and/or tune these checks. Source-Author: Jeff Ching Source-Date: Wed Aug 19 12:26:49 2020 -0700 Source-Repo: googleapis/synthtool Source-Sha: 9602086c6c5b05db77950c7f7495a2a3868f3537 Source-Link: https://github.com/googleapis/synthtool/commit/9602086c6c5b05db77950c7f7495a2a3868f3537 --- .../services/auto_ml/async_client.py | 22 ++--- .../services/auto_ml/transports/base.py | 18 ++-- google/cloud/automl_v1beta1/__init__.py | 4 +- .../services/auto_ml/async_client.py | 8 +- tests/unit/gapic/automl_v1/test_auto_ml.py | 36 ++++---- .../unit/gapic/automl_v1beta1/test_auto_ml.py | 90 +++++++++---------- 6 files changed, 89 insertions(+), 89 deletions(-) diff --git a/google/cloud/automl_v1/services/auto_ml/async_client.py b/google/cloud/automl_v1/services/auto_ml/async_client.py index 2b7f9c5c..3b4d13e2 100644 --- a/google/cloud/automl_v1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1/services/auto_ml/async_client.py @@ -79,10 +79,10 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT - model_path = staticmethod(AutoMlClient.model_path) - dataset_path = staticmethod(AutoMlClient.dataset_path) + model_path = staticmethod(AutoMlClient.model_path) + from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file @@ -289,7 +289,7 @@ async def get_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -371,7 +371,7 @@ async def list_datasets( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -559,7 +559,7 @@ async def delete_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -864,7 +864,7 @@ async def get_annotation_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1037,7 +1037,7 @@ async def get_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1119,7 +1119,7 @@ async def list_models( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1222,7 +1222,7 @@ async def delete_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1711,7 +1711,7 @@ async def get_model_evaluation( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1816,7 +1816,7 @@ async def list_model_evaluations( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1/services/auto_ml/transports/base.py b/google/cloud/automl_v1/services/auto_ml/transports/base.py index 5e230105..1fb91c88 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/base.py @@ -122,7 +122,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -135,7 +135,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -151,7 +151,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -170,7 +170,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -186,7 +186,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -199,7 +199,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -212,7 +212,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -237,7 +237,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -250,7 +250,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 30db2703..44f619cb 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -149,6 +149,7 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", + "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -227,7 +228,6 @@ "OutputConfig", "PredictRequest", "PredictResponse", - "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "AutoMlClient", + "PredictionServiceClient", ) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index de28be56..402d3068 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -87,13 +87,13 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT - dataset_path = staticmethod(AutoMlClient.dataset_path) - - table_spec_path = staticmethod(AutoMlClient.table_spec_path) + model_path = staticmethod(AutoMlClient.model_path) column_spec_path = staticmethod(AutoMlClient.column_spec_path) - model_path = staticmethod(AutoMlClient.model_path) + dataset_path = staticmethod(AutoMlClient.dataset_path) + + table_spec_path = staticmethod(AutoMlClient.table_spec_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file diff --git a/tests/unit/gapic/automl_v1/test_auto_ml.py b/tests/unit/gapic/automl_v1/test_auto_ml.py index 42ad394e..2ea4c975 100644 --- a/tests/unit/gapic/automl_v1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1/test_auto_ml.py @@ -4929,53 +4929,53 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_model_path(): +def test_dataset_path(): project = "squid" location = "clam" - model = "whelk" + dataset = "whelk" - expected = "projects/{project}/locations/{location}/models/{model}".format( - project=project, location=location, model=model, + expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( + project=project, location=location, dataset=dataset, ) - actual = AutoMlClient.model_path(project, location, model) + actual = AutoMlClient.dataset_path(project, location, dataset) assert expected == actual -def test_parse_model_path(): +def test_parse_dataset_path(): expected = { "project": "octopus", "location": "oyster", - "model": "nudibranch", + "dataset": "nudibranch", } - path = AutoMlClient.model_path(**expected) + path = AutoMlClient.dataset_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_model_path(path) + actual = AutoMlClient.parse_dataset_path(path) assert expected == actual -def test_dataset_path(): +def test_model_path(): project = "squid" location = "clam" - dataset = "whelk" + model = "whelk" - expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( - project=project, location=location, dataset=dataset, + expected = "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, ) - actual = AutoMlClient.dataset_path(project, location, dataset) + actual = AutoMlClient.model_path(project, location, model) assert expected == actual -def test_parse_dataset_path(): +def test_parse_model_path(): expected = { "project": "octopus", "location": "oyster", - "dataset": "nudibranch", + "model": "nudibranch", } - path = AutoMlClient.dataset_path(**expected) + path = AutoMlClient.model_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_dataset_path(path) + actual = AutoMlClient.parse_model_path(path) assert expected == actual diff --git a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py index c6b7d4b3..ea0dcddb 100644 --- a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py @@ -6489,55 +6489,28 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_dataset_path(): +def test_model_path(): project = "squid" location = "clam" - dataset = "whelk" + model = "whelk" - expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( - project=project, location=location, dataset=dataset, + expected = "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, ) - actual = AutoMlClient.dataset_path(project, location, dataset) + actual = AutoMlClient.model_path(project, location, model) assert expected == actual -def test_parse_dataset_path(): +def test_parse_model_path(): expected = { "project": "octopus", "location": "oyster", - "dataset": "nudibranch", - } - path = AutoMlClient.dataset_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_dataset_path(path) - assert expected == actual - - -def test_table_spec_path(): - project = "squid" - location = "clam" - dataset = "whelk" - table_spec = "octopus" - - expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( - project=project, location=location, dataset=dataset, table_spec=table_spec, - ) - actual = AutoMlClient.table_spec_path(project, location, dataset, table_spec) - assert expected == actual - - -def test_parse_table_spec_path(): - expected = { - "project": "oyster", - "location": "nudibranch", - "dataset": "cuttlefish", - "table_spec": "mussel", + "model": "nudibranch", } - path = AutoMlClient.table_spec_path(**expected) + path = AutoMlClient.model_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_table_spec_path(path) + actual = AutoMlClient.parse_model_path(path) assert expected == actual @@ -6576,28 +6549,55 @@ def test_parse_column_spec_path(): assert expected == actual -def test_model_path(): +def test_dataset_path(): project = "squid" location = "clam" - model = "whelk" + dataset = "whelk" - expected = "projects/{project}/locations/{location}/models/{model}".format( - project=project, location=location, model=model, + expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( + project=project, location=location, dataset=dataset, ) - actual = AutoMlClient.model_path(project, location, model) + actual = AutoMlClient.dataset_path(project, location, dataset) assert expected == actual -def test_parse_model_path(): +def test_parse_dataset_path(): expected = { "project": "octopus", "location": "oyster", - "model": "nudibranch", + "dataset": "nudibranch", } - path = AutoMlClient.model_path(**expected) + path = AutoMlClient.dataset_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_model_path(path) + actual = AutoMlClient.parse_dataset_path(path) + assert expected == actual + + +def test_table_spec_path(): + project = "squid" + location = "clam" + dataset = "whelk" + table_spec = "octopus" + + expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( + project=project, location=location, dataset=dataset, table_spec=table_spec, + ) + actual = AutoMlClient.table_spec_path(project, location, dataset, table_spec) + assert expected == actual + + +def test_parse_table_spec_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "dataset": "cuttlefish", + "table_spec": "mussel", + } + path = AutoMlClient.table_spec_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_table_spec_path(path) assert expected == actual From 804cc6687371c531138733abce9e40ad0dc61493 Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:47:44 -0700 Subject: [PATCH 03/25] chore: upgrade gapic-generator-python to 0.32.2 PiperOrigin-RevId: 328157915 Source-Author: Google APIs Source-Date: Mon Aug 24 09:54:09 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: f75a734e2c257765764074562f191f0e130c34e5 Source-Link: https://github.com/googleapis/googleapis/commit/f75a734e2c257765764074562f191f0e130c34e5 --- .../services/auto_ml/async_client.py | 18 +-- .../services/auto_ml/transports/base.py | 20 ++-- .../prediction_service/transports/base.py | 2 +- .../services/auto_ml/async_client.py | 4 +- .../services/auto_ml/transports/base.py | 2 +- .../prediction_service/transports/base.py | 2 +- synth.metadata | 4 +- tests/unit/gapic/automl_v1/test_auto_ml.py | 36 +++--- .../unit/gapic/automl_v1beta1/test_auto_ml.py | 104 +++++++++--------- 9 files changed, 96 insertions(+), 96 deletions(-) diff --git a/google/cloud/automl_v1/services/auto_ml/async_client.py b/google/cloud/automl_v1/services/auto_ml/async_client.py index 3b4d13e2..d37bc048 100644 --- a/google/cloud/automl_v1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1/services/auto_ml/async_client.py @@ -289,7 +289,7 @@ async def get_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -371,7 +371,7 @@ async def list_datasets( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -559,7 +559,7 @@ async def delete_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -864,7 +864,7 @@ async def get_annotation_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1037,7 +1037,7 @@ async def get_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1119,7 +1119,7 @@ async def list_models( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1222,7 +1222,7 @@ async def delete_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1711,7 +1711,7 @@ async def get_model_evaluation( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1816,7 +1816,7 @@ async def list_model_evaluations( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1/services/auto_ml/transports/base.py b/google/cloud/automl_v1/services/auto_ml/transports/base.py index 1fb91c88..b1e12781 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth +from google import auth # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore @@ -122,7 +122,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -135,7 +135,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -151,7 +151,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -170,7 +170,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -186,7 +186,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -199,7 +199,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -212,7 +212,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -237,7 +237,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -250,7 +250,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1/services/prediction_service/transports/base.py b/google/cloud/automl_v1/services/prediction_service/transports/base.py index 349d8793..f019a8dc 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/base.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth +from google import auth # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index 402d3068..28bd67f1 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -91,10 +91,10 @@ class AutoMlAsyncClient: column_spec_path = staticmethod(AutoMlClient.column_spec_path) - dataset_path = staticmethod(AutoMlClient.dataset_path) - table_spec_path = staticmethod(AutoMlClient.table_spec_path) + dataset_path = staticmethod(AutoMlClient.dataset_path) + from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py index d50f2201..642c9f7b 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth +from google import auth # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py index bb674eca..04857f4c 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth +from google import auth # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/synth.metadata b/synth.metadata index bf69619d..d3504c0f 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "17de2b31f9450385e739bedeeaac6e1ec4f239a8", - "internalRef": "327504150" + "sha": "f75a734e2c257765764074562f191f0e130c34e5", + "internalRef": "328157915" } }, { diff --git a/tests/unit/gapic/automl_v1/test_auto_ml.py b/tests/unit/gapic/automl_v1/test_auto_ml.py index 2ea4c975..cf1dca89 100644 --- a/tests/unit/gapic/automl_v1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1/test_auto_ml.py @@ -1038,8 +1038,8 @@ def test_list_datasets_pages(): RuntimeError, ) pages = list(client.list_datasets(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -1103,10 +1103,10 @@ async def test_list_datasets_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_datasets(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_datasets(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_update_dataset( @@ -2862,8 +2862,8 @@ def test_list_models_pages(): RuntimeError, ) pages = list(client.list_models(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -2919,10 +2919,10 @@ async def test_list_models_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_models(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_models(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelRequest): @@ -4459,8 +4459,8 @@ def test_list_model_evaluations_pages(): RuntimeError, ) pages = list(client.list_model_evaluations(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -4544,10 +4544,10 @@ async def test_list_model_evaluations_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_model_evaluations(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_model_evaluations(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_credentials_transport_error(): diff --git a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py index ea0dcddb..13a4d1ce 100644 --- a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py @@ -1079,8 +1079,8 @@ def test_list_datasets_pages(): RuntimeError, ) pages = list(client.list_datasets(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -1144,10 +1144,10 @@ async def test_list_datasets_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_datasets(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_datasets(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_update_dataset( @@ -2711,8 +2711,8 @@ def test_list_table_specs_pages(): RuntimeError, ) pages = list(client.list_table_specs(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -2784,10 +2784,10 @@ async def test_list_table_specs_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_table_specs(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_table_specs(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_update_table_spec( @@ -3494,8 +3494,8 @@ def test_list_column_specs_pages(): RuntimeError, ) pages = list(client.list_column_specs(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -3567,10 +3567,10 @@ async def test_list_column_specs_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_column_specs(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_column_specs(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_update_column_spec( @@ -4455,8 +4455,8 @@ def test_list_models_pages(): RuntimeError, ) pages = list(client.list_models(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -4512,10 +4512,10 @@ async def test_list_models_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_models(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_models(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelRequest): @@ -6013,8 +6013,8 @@ def test_list_model_evaluations_pages(): RuntimeError, ) pages = list(client.list_model_evaluations(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -6098,10 +6098,10 @@ async def test_list_model_evaluations_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_model_evaluations(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_model_evaluations(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_credentials_transport_error(): @@ -6549,55 +6549,55 @@ def test_parse_column_spec_path(): assert expected == actual -def test_dataset_path(): +def test_table_spec_path(): project = "squid" location = "clam" dataset = "whelk" + table_spec = "octopus" - expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( - project=project, location=location, dataset=dataset, + expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( + project=project, location=location, dataset=dataset, table_spec=table_spec, ) - actual = AutoMlClient.dataset_path(project, location, dataset) + actual = AutoMlClient.table_spec_path(project, location, dataset, table_spec) assert expected == actual -def test_parse_dataset_path(): +def test_parse_table_spec_path(): expected = { - "project": "octopus", - "location": "oyster", - "dataset": "nudibranch", + "project": "oyster", + "location": "nudibranch", + "dataset": "cuttlefish", + "table_spec": "mussel", } - path = AutoMlClient.dataset_path(**expected) + path = AutoMlClient.table_spec_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_dataset_path(path) + actual = AutoMlClient.parse_table_spec_path(path) assert expected == actual -def test_table_spec_path(): +def test_dataset_path(): project = "squid" location = "clam" dataset = "whelk" - table_spec = "octopus" - expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( - project=project, location=location, dataset=dataset, table_spec=table_spec, + expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( + project=project, location=location, dataset=dataset, ) - actual = AutoMlClient.table_spec_path(project, location, dataset, table_spec) + actual = AutoMlClient.dataset_path(project, location, dataset) assert expected == actual -def test_parse_table_spec_path(): +def test_parse_dataset_path(): expected = { - "project": "oyster", - "location": "nudibranch", - "dataset": "cuttlefish", - "table_spec": "mussel", + "project": "octopus", + "location": "oyster", + "dataset": "nudibranch", } - path = AutoMlClient.table_spec_path(**expected) + path = AutoMlClient.dataset_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_table_spec_path(path) + actual = AutoMlClient.parse_dataset_path(path) assert expected == actual From aa27d8219ab4342c9c904bc2fdf6b14797308b12 Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:48:47 -0700 Subject: [PATCH 04/25] feat: added google.cloud.assuredworkloads.v1beta1.AssuredWorkloadsService service PiperOrigin-RevId: 328756245 Source-Author: Google APIs Source-Date: Thu Aug 27 09:48:55 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: 56f0db80b2378552f0323ac56ed6e35f51b1a53a Source-Link: https://github.com/googleapis/googleapis/commit/56f0db80b2378552f0323ac56ed6e35f51b1a53a --- google/cloud/automl_v1/__init__.py | 4 +- google/cloud/automl_v1beta1/__init__.py | 4 +- .../services/auto_ml/async_client.py | 8 +- synth.metadata | 4 +- .../unit/gapic/automl_v1beta1/test_auto_ml.py | 104 +++++++++--------- 5 files changed, 62 insertions(+), 62 deletions(-) diff --git a/google/cloud/automl_v1/__init__.py b/google/cloud/automl_v1/__init__.py index b5f76f81..6f22bb65 100644 --- a/google/cloud/automl_v1/__init__.py +++ b/google/cloud/automl_v1/__init__.py @@ -104,6 +104,7 @@ __all__ = ( "AnnotationPayload", "AnnotationSpec", + "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -164,7 +165,6 @@ "OutputConfig", "PredictRequest", "PredictResponse", - "PredictionServiceClient", "TextClassificationDatasetMetadata", "TextClassificationModelMetadata", "TextExtractionAnnotation", @@ -185,5 +185,5 @@ "UndeployModelRequest", "UpdateDatasetRequest", "UpdateModelRequest", - "AutoMlClient", + "PredictionServiceClient", ) diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 44f619cb..30db2703 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -149,7 +149,6 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", - "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -228,6 +227,7 @@ "OutputConfig", "PredictRequest", "PredictResponse", + "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "PredictionServiceClient", + "AutoMlClient", ) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index 28bd67f1..d7fed730 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -87,14 +87,14 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT - model_path = staticmethod(AutoMlClient.model_path) - - column_spec_path = staticmethod(AutoMlClient.column_spec_path) - table_spec_path = staticmethod(AutoMlClient.table_spec_path) + model_path = staticmethod(AutoMlClient.model_path) + dataset_path = staticmethod(AutoMlClient.dataset_path) + column_spec_path = staticmethod(AutoMlClient.column_spec_path) + from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file diff --git a/synth.metadata b/synth.metadata index d3504c0f..081699c8 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "f75a734e2c257765764074562f191f0e130c34e5", - "internalRef": "328157915" + "sha": "56f0db80b2378552f0323ac56ed6e35f51b1a53a", + "internalRef": "328756245" } }, { diff --git a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py index 13a4d1ce..06a96e04 100644 --- a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py @@ -6489,6 +6489,33 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client +def test_table_spec_path(): + project = "squid" + location = "clam" + dataset = "whelk" + table_spec = "octopus" + + expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( + project=project, location=location, dataset=dataset, table_spec=table_spec, + ) + actual = AutoMlClient.table_spec_path(project, location, dataset, table_spec) + assert expected == actual + + +def test_parse_table_spec_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "dataset": "cuttlefish", + "table_spec": "mussel", + } + path = AutoMlClient.table_spec_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_table_spec_path(path) + assert expected == actual + + def test_model_path(): project = "squid" location = "clam" @@ -6514,6 +6541,31 @@ def test_parse_model_path(): assert expected == actual +def test_dataset_path(): + project = "squid" + location = "clam" + dataset = "whelk" + + expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( + project=project, location=location, dataset=dataset, + ) + actual = AutoMlClient.dataset_path(project, location, dataset) + assert expected == actual + + +def test_parse_dataset_path(): + expected = { + "project": "octopus", + "location": "oyster", + "dataset": "nudibranch", + } + path = AutoMlClient.dataset_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_dataset_path(path) + assert expected == actual + + def test_column_spec_path(): project = "squid" location = "clam" @@ -6549,58 +6601,6 @@ def test_parse_column_spec_path(): assert expected == actual -def test_table_spec_path(): - project = "squid" - location = "clam" - dataset = "whelk" - table_spec = "octopus" - - expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( - project=project, location=location, dataset=dataset, table_spec=table_spec, - ) - actual = AutoMlClient.table_spec_path(project, location, dataset, table_spec) - assert expected == actual - - -def test_parse_table_spec_path(): - expected = { - "project": "oyster", - "location": "nudibranch", - "dataset": "cuttlefish", - "table_spec": "mussel", - } - path = AutoMlClient.table_spec_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_table_spec_path(path) - assert expected == actual - - -def test_dataset_path(): - project = "squid" - location = "clam" - dataset = "whelk" - - expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( - project=project, location=location, dataset=dataset, - ) - actual = AutoMlClient.dataset_path(project, location, dataset) - assert expected == actual - - -def test_parse_dataset_path(): - expected = { - "project": "octopus", - "location": "oyster", - "dataset": "nudibranch", - } - path = AutoMlClient.dataset_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_dataset_path(path) - assert expected == actual - - def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() From 972edb5e5f8802c78ebd12ef3615d7dede1681a7 Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:51:33 -0700 Subject: [PATCH 05/25] feat!: Updated third_party Cloud Build clients with new Build message fields: - `service_account`, which is available to members of our closed alpha - STACKDRIVER_ONLY and CLOUD_LOGGING_ONLY logging modes - `dynamic_substitutions` option BREAKING CHANGE: The WorkerPool API in the v1 surface has been long deprecated, so it has been deleted from the v1 surface. Alpha WorkerPool customers who want to call the WorkerPool API can use gcloud. PiperOrigin-RevId: 330504082 Source-Author: Google APIs Source-Date: Tue Sep 8 07:21:07 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: 48ce8878cd4c54cf247de826ac53c1414b0345bd Source-Link: https://github.com/googleapis/googleapis/commit/48ce8878cd4c54cf247de826ac53c1414b0345bd --- .../services/auto_ml/async_client.py | 18 +-- .../services/auto_ml/transports/base.py | 18 +-- google/cloud/automl_v1beta1/__init__.py | 4 +- .../services/auto_ml/async_client.py | 8 +- synth.metadata | 4 +- .../unit/gapic/automl_v1beta1/test_auto_ml.py | 104 +++++++++--------- 6 files changed, 78 insertions(+), 78 deletions(-) diff --git a/google/cloud/automl_v1/services/auto_ml/async_client.py b/google/cloud/automl_v1/services/auto_ml/async_client.py index d37bc048..3b4d13e2 100644 --- a/google/cloud/automl_v1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1/services/auto_ml/async_client.py @@ -289,7 +289,7 @@ async def get_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -371,7 +371,7 @@ async def list_datasets( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -559,7 +559,7 @@ async def delete_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -864,7 +864,7 @@ async def get_annotation_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1037,7 +1037,7 @@ async def get_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1119,7 +1119,7 @@ async def list_models( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1222,7 +1222,7 @@ async def delete_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1711,7 +1711,7 @@ async def get_model_evaluation( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1816,7 +1816,7 @@ async def list_model_evaluations( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1/services/auto_ml/transports/base.py b/google/cloud/automl_v1/services/auto_ml/transports/base.py index b1e12781..7deddee8 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/base.py @@ -122,7 +122,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -135,7 +135,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -151,7 +151,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -170,7 +170,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -186,7 +186,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -199,7 +199,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -212,7 +212,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -237,7 +237,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -250,7 +250,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 30db2703..44f619cb 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -149,6 +149,7 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", + "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -227,7 +228,6 @@ "OutputConfig", "PredictRequest", "PredictResponse", - "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "AutoMlClient", + "PredictionServiceClient", ) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index d7fed730..27be88c5 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -87,14 +87,14 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT - table_spec_path = staticmethod(AutoMlClient.table_spec_path) - - model_path = staticmethod(AutoMlClient.model_path) - dataset_path = staticmethod(AutoMlClient.dataset_path) column_spec_path = staticmethod(AutoMlClient.column_spec_path) + table_spec_path = staticmethod(AutoMlClient.table_spec_path) + + model_path = staticmethod(AutoMlClient.model_path) + from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file diff --git a/synth.metadata b/synth.metadata index 081699c8..add93f7b 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "56f0db80b2378552f0323ac56ed6e35f51b1a53a", - "internalRef": "328756245" + "sha": "48ce8878cd4c54cf247de826ac53c1414b0345bd", + "internalRef": "330504082" } }, { diff --git a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py index 06a96e04..7b346759 100644 --- a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py @@ -6489,58 +6489,6 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_table_spec_path(): - project = "squid" - location = "clam" - dataset = "whelk" - table_spec = "octopus" - - expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( - project=project, location=location, dataset=dataset, table_spec=table_spec, - ) - actual = AutoMlClient.table_spec_path(project, location, dataset, table_spec) - assert expected == actual - - -def test_parse_table_spec_path(): - expected = { - "project": "oyster", - "location": "nudibranch", - "dataset": "cuttlefish", - "table_spec": "mussel", - } - path = AutoMlClient.table_spec_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_table_spec_path(path) - assert expected == actual - - -def test_model_path(): - project = "squid" - location = "clam" - model = "whelk" - - expected = "projects/{project}/locations/{location}/models/{model}".format( - project=project, location=location, model=model, - ) - actual = AutoMlClient.model_path(project, location, model) - assert expected == actual - - -def test_parse_model_path(): - expected = { - "project": "octopus", - "location": "oyster", - "model": "nudibranch", - } - path = AutoMlClient.model_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_model_path(path) - assert expected == actual - - def test_dataset_path(): project = "squid" location = "clam" @@ -6601,6 +6549,58 @@ def test_parse_column_spec_path(): assert expected == actual +def test_table_spec_path(): + project = "squid" + location = "clam" + dataset = "whelk" + table_spec = "octopus" + + expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( + project=project, location=location, dataset=dataset, table_spec=table_spec, + ) + actual = AutoMlClient.table_spec_path(project, location, dataset, table_spec) + assert expected == actual + + +def test_parse_table_spec_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "dataset": "cuttlefish", + "table_spec": "mussel", + } + path = AutoMlClient.table_spec_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_table_spec_path(path) + assert expected == actual + + +def test_model_path(): + project = "squid" + location = "clam" + model = "whelk" + + expected = "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, + ) + actual = AutoMlClient.model_path(project, location, model) + assert expected == actual + + +def test_parse_model_path(): + expected = { + "project": "octopus", + "location": "oyster", + "model": "nudibranch", + } + path = AutoMlClient.model_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_model_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() From 397c3bbbefa6e02f887a06077ef48d72d681917d Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:52:34 -0700 Subject: [PATCH 06/25] chore: update python microgen version to 0.33.0 PiperOrigin-RevId: 331031262 Source-Author: Google APIs Source-Date: Thu Sep 10 15:35:17 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: 6a18a3c50ffd62de53dd2e44f599d6696580f90b Source-Link: https://github.com/googleapis/googleapis/commit/6a18a3c50ffd62de53dd2e44f599d6696580f90b --- google/cloud/automl_v1/__init__.py | 4 +- .../services/auto_ml/async_client.py | 40 +- .../automl_v1/services/auto_ml/client.py | 70 ++- .../services/auto_ml/transports/base.py | 18 +- .../services/auto_ml/transports/grpc.py | 46 +- .../auto_ml/transports/grpc_asyncio.py | 51 +- .../prediction_service/async_client.py | 19 +- .../services/prediction_service/client.py | 70 ++- .../prediction_service/transports/grpc.py | 46 +- .../transports/grpc_asyncio.py | 51 +- google/cloud/automl_v1beta1/__init__.py | 4 +- .../services/auto_ml/async_client.py | 30 +- .../automl_v1beta1/services/auto_ml/client.py | 70 ++- .../services/auto_ml/transports/grpc.py | 46 +- .../auto_ml/transports/grpc_asyncio.py | 51 +- .../prediction_service/async_client.py | 19 +- .../services/prediction_service/client.py | 70 ++- .../prediction_service/transports/grpc.py | 46 +- .../transports/grpc_asyncio.py | 51 +- synth.metadata | 4 +- tests/unit/gapic/automl_v1/test_auto_ml.py | 471 +++++++-------- .../automl_v1/test_prediction_service.py | 494 ++++++++-------- .../unit/gapic/automl_v1beta1/test_auto_ml.py | 545 +++++++++--------- .../automl_v1beta1/test_prediction_service.py | 494 ++++++++-------- 24 files changed, 1601 insertions(+), 1209 deletions(-) diff --git a/google/cloud/automl_v1/__init__.py b/google/cloud/automl_v1/__init__.py index 6f22bb65..b5f76f81 100644 --- a/google/cloud/automl_v1/__init__.py +++ b/google/cloud/automl_v1/__init__.py @@ -104,7 +104,6 @@ __all__ = ( "AnnotationPayload", "AnnotationSpec", - "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -165,6 +164,7 @@ "OutputConfig", "PredictRequest", "PredictResponse", + "PredictionServiceClient", "TextClassificationDatasetMetadata", "TextClassificationModelMetadata", "TextExtractionAnnotation", @@ -185,5 +185,5 @@ "UndeployModelRequest", "UpdateDatasetRequest", "UpdateModelRequest", - "PredictionServiceClient", + "AutoMlClient", ) diff --git a/google/cloud/automl_v1/services/auto_ml/async_client.py b/google/cloud/automl_v1/services/auto_ml/async_client.py index 3b4d13e2..9dd21f72 100644 --- a/google/cloud/automl_v1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1/services/auto_ml/async_client.py @@ -80,8 +80,9 @@ class AutoMlAsyncClient: DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT dataset_path = staticmethod(AutoMlClient.dataset_path) - + parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) model_path = staticmethod(AutoMlClient.model_path) + parse_model_path = staticmethod(AutoMlClient.parse_model_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file @@ -112,16 +113,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport @@ -289,7 +293,7 @@ async def get_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -371,7 +375,7 @@ async def list_datasets( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -559,7 +563,7 @@ async def delete_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -864,7 +868,7 @@ async def get_annotation_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1037,7 +1041,7 @@ async def get_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1119,7 +1123,7 @@ async def list_models( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1222,7 +1226,7 @@ async def delete_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1711,7 +1715,7 @@ async def get_model_evaluation( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1816,7 +1820,7 @@ async def list_model_evaluations( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1/services/auto_ml/client.py b/google/cloud/automl_v1/services/auto_ml/client.py index e615ce00..6cace8ae 100644 --- a/google/cloud/automl_v1/services/auto_ml/client.py +++ b/google/cloud/automl_v1/services/auto_ml/client.py @@ -16,6 +16,7 @@ # from collections import OrderedDict +from distutils import util import os import re from typing import Callable, Dict, Sequence, Tuple, Type, Union @@ -27,6 +28,7 @@ from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore @@ -215,16 +217,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -240,25 +245,43 @@ def __init__( if client_options is None: client_options = ClientOptions.ClientOptions() - if client_options.api_endpoint is None: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + ssl_credentials = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + import grpc # type: ignore + + cert, key = client_options.client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + is_mtls = True + else: + creds = SslCredentials() + is_mtls = creds.is_mtls + ssl_credentials = creds.ssl_credentials if is_mtls else None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") if use_mtls_env == "never": - client_options.api_endpoint = self.DEFAULT_ENDPOINT + api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - has_client_cert_source = ( - client_options.client_cert_source is not None - or mtls.has_default_client_cert_source() - ) - client_options.api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT - if has_client_cert_source - else self.DEFAULT_ENDPOINT + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -282,10 +305,9 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=client_options.api_endpoint, + host=api_endpoint, scopes=client_options.scopes, - api_mtls_endpoint=client_options.api_endpoint, - client_cert_source=client_options.client_cert_source, + ssl_channel_credentials=ssl_credentials, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1/services/auto_ml/transports/base.py b/google/cloud/automl_v1/services/auto_ml/transports/base.py index 7deddee8..b1e12781 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/base.py @@ -122,7 +122,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -135,7 +135,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -151,7 +151,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -170,7 +170,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -186,7 +186,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -199,7 +199,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -212,7 +212,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -237,7 +237,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -250,7 +250,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py index 100f50f6..b957e5cd 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py @@ -15,6 +15,7 @@ # limitations under the License. # +import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -24,7 +25,6 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore - import grpc # type: ignore from google.cloud.automl_v1.types import annotation_spec @@ -78,6 +78,7 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -98,14 +99,16 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -128,6 +131,11 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -158,6 +166,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) self._stubs = {} # type: Dict[str, Callable] @@ -223,13 +248,6 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py b/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py index 39e15a79..0778c063 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py @@ -15,11 +15,13 @@ # limitations under the License. # +import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore +from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -120,6 +122,7 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -141,14 +144,16 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -171,12 +176,22 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -196,6 +211,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) # Run the base constructor. super().__init__( @@ -216,13 +248,6 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/prediction_service/async_client.py b/google/cloud/automl_v1/services/prediction_service/async_client.py index df141602..fe1d2226 100644 --- a/google/cloud/automl_v1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1/services/prediction_service/async_client.py @@ -82,16 +82,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1/services/prediction_service/client.py b/google/cloud/automl_v1/services/prediction_service/client.py index 2ccfd9fc..d557fd9b 100644 --- a/google/cloud/automl_v1/services/prediction_service/client.py +++ b/google/cloud/automl_v1/services/prediction_service/client.py @@ -16,6 +16,7 @@ # from collections import OrderedDict +from distutils import util import os import re from typing import Callable, Dict, Sequence, Tuple, Type, Union @@ -27,6 +28,7 @@ from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore @@ -161,16 +163,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -186,25 +191,43 @@ def __init__( if client_options is None: client_options = ClientOptions.ClientOptions() - if client_options.api_endpoint is None: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + ssl_credentials = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + import grpc # type: ignore + + cert, key = client_options.client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + is_mtls = True + else: + creds = SslCredentials() + is_mtls = creds.is_mtls + ssl_credentials = creds.ssl_credentials if is_mtls else None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") if use_mtls_env == "never": - client_options.api_endpoint = self.DEFAULT_ENDPOINT + api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - has_client_cert_source = ( - client_options.client_cert_source is not None - or mtls.has_default_client_cert_source() - ) - client_options.api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT - if has_client_cert_source - else self.DEFAULT_ENDPOINT + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -228,10 +251,9 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=client_options.api_endpoint, + host=api_endpoint, scopes=client_options.scopes, - api_mtls_endpoint=client_options.api_endpoint, - client_cert_source=client_options.client_cert_source, + ssl_channel_credentials=ssl_credentials, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py index e4508add..9a2c8e9b 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py @@ -15,6 +15,7 @@ # limitations under the License. # +import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -24,7 +25,6 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore - import grpc # type: ignore from google.cloud.automl_v1.types import prediction_service @@ -61,6 +61,7 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -81,14 +82,16 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -111,6 +114,11 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -141,6 +149,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) self._stubs = {} # type: Dict[str, Callable] @@ -206,13 +231,6 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py b/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py index f92ad264..eddcb6ab 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py @@ -15,11 +15,13 @@ # limitations under the License. # +import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore +from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -103,6 +105,7 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -124,14 +127,16 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -154,12 +159,22 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -179,6 +194,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) # Run the base constructor. super().__init__( @@ -199,13 +231,6 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 44f619cb..30db2703 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -149,7 +149,6 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", - "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -228,6 +227,7 @@ "OutputConfig", "PredictRequest", "PredictResponse", + "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "PredictionServiceClient", + "AutoMlClient", ) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index 27be88c5..1d9cb516 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -87,13 +87,14 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT - dataset_path = staticmethod(AutoMlClient.dataset_path) - column_spec_path = staticmethod(AutoMlClient.column_spec_path) - - table_spec_path = staticmethod(AutoMlClient.table_spec_path) - + parse_column_spec_path = staticmethod(AutoMlClient.parse_column_spec_path) + dataset_path = staticmethod(AutoMlClient.dataset_path) + parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) model_path = staticmethod(AutoMlClient.model_path) + parse_model_path = staticmethod(AutoMlClient.parse_model_path) + table_spec_path = staticmethod(AutoMlClient.table_spec_path) + parse_table_spec_path = staticmethod(AutoMlClient.parse_table_spec_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file @@ -124,16 +125,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1beta1/services/auto_ml/client.py b/google/cloud/automl_v1beta1/services/auto_ml/client.py index 9416b524..dd44b58e 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/client.py @@ -16,6 +16,7 @@ # from collections import OrderedDict +from distutils import util import os import re from typing import Callable, Dict, Sequence, Tuple, Type, Union @@ -27,6 +28,7 @@ from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore @@ -263,16 +265,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -288,25 +293,43 @@ def __init__( if client_options is None: client_options = ClientOptions.ClientOptions() - if client_options.api_endpoint is None: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + ssl_credentials = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + import grpc # type: ignore + + cert, key = client_options.client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + is_mtls = True + else: + creds = SslCredentials() + is_mtls = creds.is_mtls + ssl_credentials = creds.ssl_credentials if is_mtls else None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") if use_mtls_env == "never": - client_options.api_endpoint = self.DEFAULT_ENDPOINT + api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - has_client_cert_source = ( - client_options.client_cert_source is not None - or mtls.has_default_client_cert_source() - ) - client_options.api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT - if has_client_cert_source - else self.DEFAULT_ENDPOINT + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -330,10 +353,9 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=client_options.api_endpoint, + host=api_endpoint, scopes=client_options.scopes, - api_mtls_endpoint=client_options.api_endpoint, - client_cert_source=client_options.client_cert_source, + ssl_channel_credentials=ssl_credentials, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py index a3c183e4..a8cb2fd7 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py @@ -15,6 +15,7 @@ # limitations under the License. # +import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -24,7 +25,6 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore - import grpc # type: ignore from google.cloud.automl_v1beta1.types import annotation_spec @@ -81,6 +81,7 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -101,14 +102,16 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -131,6 +134,11 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -161,6 +169,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) self._stubs = {} # type: Dict[str, Callable] @@ -226,13 +251,6 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py index c8d24dad..a977ad45 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py @@ -15,11 +15,13 @@ # limitations under the License. # +import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore +from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -123,6 +125,7 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -144,14 +147,16 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -174,12 +179,22 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -199,6 +214,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) # Run the base constructor. super().__init__( @@ -219,13 +251,6 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py index cd313402..3974a08c 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py @@ -82,16 +82,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1beta1/services/prediction_service/client.py b/google/cloud/automl_v1beta1/services/prediction_service/client.py index 81cb0649..747f4c4b 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/client.py @@ -16,6 +16,7 @@ # from collections import OrderedDict +from distutils import util import os import re from typing import Callable, Dict, Sequence, Tuple, Type, Union @@ -27,6 +28,7 @@ from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore @@ -161,16 +163,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -186,25 +191,43 @@ def __init__( if client_options is None: client_options = ClientOptions.ClientOptions() - if client_options.api_endpoint is None: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + ssl_credentials = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + import grpc # type: ignore + + cert, key = client_options.client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + is_mtls = True + else: + creds = SslCredentials() + is_mtls = creds.is_mtls + ssl_credentials = creds.ssl_credentials if is_mtls else None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") if use_mtls_env == "never": - client_options.api_endpoint = self.DEFAULT_ENDPOINT + api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - has_client_cert_source = ( - client_options.client_cert_source is not None - or mtls.has_default_client_cert_source() - ) - client_options.api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT - if has_client_cert_source - else self.DEFAULT_ENDPOINT + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -228,10 +251,9 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=client_options.api_endpoint, + host=api_endpoint, scopes=client_options.scopes, - api_mtls_endpoint=client_options.api_endpoint, - client_cert_source=client_options.client_cert_source, + ssl_channel_credentials=ssl_credentials, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py index 9bc30cdd..3c484247 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py @@ -15,6 +15,7 @@ # limitations under the License. # +import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -24,7 +25,6 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore - import grpc # type: ignore from google.cloud.automl_v1beta1.types import prediction_service @@ -61,6 +61,7 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -81,14 +82,16 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -111,6 +114,11 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -141,6 +149,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) self._stubs = {} # type: Dict[str, Callable] @@ -206,13 +231,6 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py index 2c7d9712..0b1bb638 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py @@ -15,11 +15,13 @@ # limitations under the License. # +import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore +from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -103,6 +105,7 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -124,14 +127,16 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -154,12 +159,22 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -179,6 +194,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) # Run the base constructor. super().__init__( @@ -199,13 +231,6 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/synth.metadata b/synth.metadata index add93f7b..a2bb67a2 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "48ce8878cd4c54cf247de826ac53c1414b0345bd", - "internalRef": "330504082" + "sha": "6a18a3c50ffd62de53dd2e44f599d6696580f90b", + "internalRef": "331031262" } }, { diff --git a/tests/unit/gapic/automl_v1/test_auto_ml.py b/tests/unit/gapic/automl_v1/test_auto_ml.py index cf1dca89..a567c98f 100644 --- a/tests/unit/gapic/automl_v1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1/test_auto_ml.py @@ -158,15 +158,14 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -175,15 +174,14 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -192,95 +190,171 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "true"), + ( + AutoMlAsyncClient, + transports.AutoMlGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "false"), + ( + AutoMlAsyncClient, + transports.AutoMlGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + AutoMlClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlClient) +) +@mock.patch.object( + AutoMlAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlAsyncClient) +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_auto_ml_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=client_cert_source_callback, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and default_client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): - with mock.patch.object(transport_class, "__init__") as patched: + ssl_channel_creds = mock.Mock() with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, + "grpc.ssl_channel_credentials", return_value=ssl_channel_creds ): patched.return_value = None - client = client_class() + client = client_class(client_options=options) + + if use_client_cert_env == "false": + expected_ssl_channel_creds = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_ssl_channel_creds = ssl_channel_creds + expected_host = client.DEFAULT_MTLS_ENDPOINT + patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, + host=expected_host, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=expected_ssl_channel_creds, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", but client_cert_source and default_client_cert_source are None. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None ): - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.ssl_credentials", + new_callable=mock.PropertyMock, + ) as ssl_credentials_mock: + if use_client_cert_env == "false": + is_mtls_mock.return_value = False + ssl_credentials_mock.return_value = None + expected_host = client.DEFAULT_ENDPOINT + expected_ssl_channel_creds = None + else: + is_mtls_mock.return_value = True + ssl_credentials_mock.return_value = mock.Mock() + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_ssl_channel_creds = ( + ssl_credentials_mock.return_value + ) + + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + ssl_channel_credentials=expected_ssl_channel_creds, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + ): + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + is_mtls_mock.return_value = False + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -303,8 +377,7 @@ def test_auto_ml_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -330,8 +403,7 @@ def test_auto_ml_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -348,8 +420,7 @@ def test_auto_ml_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -4604,6 +4675,18 @@ def test_transport_get_channel(): assert channel +@pytest.mark.parametrize( + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4680,6 +4763,17 @@ def test_auto_ml_base_transport_with_credentials_file(): ) +def test_auto_ml_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(auth, "default") as adc, mock.patch( + "google.cloud.automl_v1.services.auto_ml.transports.AutoMlTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.AutoMlTransport() + adc.assert_called_once() + + def test_auto_ml_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -4728,179 +4822,102 @@ def test_auto_ml_host_with_port(): def test_auto_ml_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called def test_auto_ml_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_auto_ml_grpc_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], ) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_auto_ml_grpc_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - mock_cred = mock.Mock() - transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel +def test_auto_ml_transport_channel_mtls_with_client_cert_source(transport_class): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], ) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. +def test_auto_ml_transport_channel_mtls_with_adc(transport_class): mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - mock_cred = mock.Mock() - transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_auto_ml_grpc_lro_client(): diff --git a/tests/unit/gapic/automl_v1/test_prediction_service.py b/tests/unit/gapic/automl_v1/test_prediction_service.py index a0087eae..37efdce5 100644 --- a/tests/unit/gapic/automl_v1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1/test_prediction_service.py @@ -167,15 +167,14 @@ def test_prediction_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -184,15 +183,14 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -201,95 +199,185 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + PredictionServiceClient, + transports.PredictionServiceGrpcTransport, + "grpc", + "true", + ), + ( + PredictionServiceAsyncClient, + transports.PredictionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + PredictionServiceClient, + transports.PredictionServiceGrpcTransport, + "grpc", + "false", + ), + ( + PredictionServiceAsyncClient, + transports.PredictionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + PredictionServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceClient), +) +@mock.patch.object( + PredictionServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_prediction_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=client_cert_source_callback, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and default_client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): - with mock.patch.object(transport_class, "__init__") as patched: + ssl_channel_creds = mock.Mock() with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, + "grpc.ssl_channel_credentials", return_value=ssl_channel_creds ): patched.return_value = None - client = client_class() + client = client_class(client_options=options) + + if use_client_cert_env == "false": + expected_ssl_channel_creds = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_ssl_channel_creds = ssl_channel_creds + expected_host = client.DEFAULT_MTLS_ENDPOINT + patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, + host=expected_host, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=expected_ssl_channel_creds, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", but client_cert_source and default_client_cert_source are None. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None ): - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.ssl_credentials", + new_callable=mock.PropertyMock, + ) as ssl_credentials_mock: + if use_client_cert_env == "false": + is_mtls_mock.return_value = False + ssl_credentials_mock.return_value = None + expected_host = client.DEFAULT_ENDPOINT + expected_ssl_channel_creds = None + else: + is_mtls_mock.return_value = True + ssl_credentials_mock.return_value = mock.Mock() + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_ssl_channel_creds = ( + ssl_credentials_mock.return_value + ) + + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + ssl_channel_credentials=expected_ssl_channel_creds, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + ): + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + is_mtls_mock.return_value = False + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -316,8 +404,7 @@ def test_prediction_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -347,8 +434,7 @@ def test_prediction_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -367,8 +453,7 @@ def test_prediction_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -904,6 +989,21 @@ def test_transport_get_channel(): assert channel +@pytest.mark.parametrize( + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -964,6 +1064,17 @@ def test_prediction_service_base_transport_with_credentials_file(): ) +def test_prediction_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(auth, "default") as adc, mock.patch( + "google.cloud.automl_v1.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport() + adc.assert_called_once() + + def test_prediction_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -1012,179 +1123,110 @@ def test_prediction_service_host_with_port(): def test_prediction_service_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called def test_prediction_service_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_prediction_service_grpc_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], ) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_prediction_service_grpc_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint +def test_prediction_service_transport_channel_mtls_with_client_cert_source( + transport_class, ): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - mock_cred = mock.Mock() - transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], ) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. +def test_prediction_service_transport_channel_mtls_with_adc(transport_class): mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - mock_cred = mock.Mock() - transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_prediction_service_grpc_lro_client(): diff --git a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py index 7b346759..ebb97c59 100644 --- a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py @@ -168,15 +168,14 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -185,15 +184,14 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -202,95 +200,171 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "true"), + ( + AutoMlAsyncClient, + transports.AutoMlGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "false"), + ( + AutoMlAsyncClient, + transports.AutoMlGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + AutoMlClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlClient) +) +@mock.patch.object( + AutoMlAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlAsyncClient) +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_auto_ml_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=client_cert_source_callback, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and default_client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): - with mock.patch.object(transport_class, "__init__") as patched: + ssl_channel_creds = mock.Mock() with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, + "grpc.ssl_channel_credentials", return_value=ssl_channel_creds ): patched.return_value = None - client = client_class() + client = client_class(client_options=options) + + if use_client_cert_env == "false": + expected_ssl_channel_creds = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_ssl_channel_creds = ssl_channel_creds + expected_host = client.DEFAULT_MTLS_ENDPOINT + patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, + host=expected_host, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=expected_ssl_channel_creds, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", but client_cert_source and default_client_cert_source are None. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None ): - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.ssl_credentials", + new_callable=mock.PropertyMock, + ) as ssl_credentials_mock: + if use_client_cert_env == "false": + is_mtls_mock.return_value = False + ssl_credentials_mock.return_value = None + expected_host = client.DEFAULT_ENDPOINT + expected_ssl_channel_creds = None + else: + is_mtls_mock.return_value = True + ssl_credentials_mock.return_value = mock.Mock() + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_ssl_channel_creds = ( + ssl_credentials_mock.return_value + ) + + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + ssl_channel_credentials=expected_ssl_channel_creds, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + ): + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + is_mtls_mock.return_value = False + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -313,8 +387,7 @@ def test_auto_ml_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -340,8 +413,7 @@ def test_auto_ml_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -358,8 +430,7 @@ def test_auto_ml_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -6158,6 +6229,18 @@ def test_transport_get_channel(): assert channel +@pytest.mark.parametrize( + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -6240,6 +6323,17 @@ def test_auto_ml_base_transport_with_credentials_file(): ) +def test_auto_ml_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(auth, "default") as adc, mock.patch( + "google.cloud.automl_v1beta1.services.auto_ml.transports.AutoMlTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.AutoMlTransport() + adc.assert_called_once() + + def test_auto_ml_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -6288,179 +6382,102 @@ def test_auto_ml_host_with_port(): def test_auto_ml_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called def test_auto_ml_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_auto_ml_grpc_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], ) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_auto_ml_grpc_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - mock_cred = mock.Mock() - transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel +def test_auto_ml_transport_channel_mtls_with_client_cert_source(transport_class): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], ) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. +def test_auto_ml_transport_channel_mtls_with_adc(transport_class): mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - mock_cred = mock.Mock() - transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_auto_ml_grpc_lro_client(): @@ -6489,31 +6506,6 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_dataset_path(): - project = "squid" - location = "clam" - dataset = "whelk" - - expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( - project=project, location=location, dataset=dataset, - ) - actual = AutoMlClient.dataset_path(project, location, dataset) - assert expected == actual - - -def test_parse_dataset_path(): - expected = { - "project": "octopus", - "location": "oyster", - "dataset": "nudibranch", - } - path = AutoMlClient.dataset_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_dataset_path(path) - assert expected == actual - - def test_column_spec_path(): project = "squid" location = "clam" @@ -6549,30 +6541,28 @@ def test_parse_column_spec_path(): assert expected == actual -def test_table_spec_path(): +def test_dataset_path(): project = "squid" location = "clam" dataset = "whelk" - table_spec = "octopus" - expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( - project=project, location=location, dataset=dataset, table_spec=table_spec, + expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( + project=project, location=location, dataset=dataset, ) - actual = AutoMlClient.table_spec_path(project, location, dataset, table_spec) + actual = AutoMlClient.dataset_path(project, location, dataset) assert expected == actual -def test_parse_table_spec_path(): +def test_parse_dataset_path(): expected = { - "project": "oyster", - "location": "nudibranch", - "dataset": "cuttlefish", - "table_spec": "mussel", + "project": "octopus", + "location": "oyster", + "dataset": "nudibranch", } - path = AutoMlClient.table_spec_path(**expected) + path = AutoMlClient.dataset_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_table_spec_path(path) + actual = AutoMlClient.parse_dataset_path(path) assert expected == actual @@ -6601,6 +6591,33 @@ def test_parse_model_path(): assert expected == actual +def test_table_spec_path(): + project = "squid" + location = "clam" + dataset = "whelk" + table_spec = "octopus" + + expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( + project=project, location=location, dataset=dataset, table_spec=table_spec, + ) + actual = AutoMlClient.table_spec_path(project, location, dataset, table_spec) + assert expected == actual + + +def test_parse_table_spec_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "dataset": "cuttlefish", + "table_spec": "mussel", + } + path = AutoMlClient.table_spec_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_table_spec_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() diff --git a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py index c21f17b9..4d9e45a9 100644 --- a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py @@ -170,15 +170,14 @@ def test_prediction_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -187,15 +186,14 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -204,95 +202,185 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + PredictionServiceClient, + transports.PredictionServiceGrpcTransport, + "grpc", + "true", + ), + ( + PredictionServiceAsyncClient, + transports.PredictionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + PredictionServiceClient, + transports.PredictionServiceGrpcTransport, + "grpc", + "false", + ), + ( + PredictionServiceAsyncClient, + transports.PredictionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + PredictionServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceClient), +) +@mock.patch.object( + PredictionServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_prediction_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=client_cert_source_callback, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and default_client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): - with mock.patch.object(transport_class, "__init__") as patched: + ssl_channel_creds = mock.Mock() with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, + "grpc.ssl_channel_credentials", return_value=ssl_channel_creds ): patched.return_value = None - client = client_class() + client = client_class(client_options=options) + + if use_client_cert_env == "false": + expected_ssl_channel_creds = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_ssl_channel_creds = ssl_channel_creds + expected_host = client.DEFAULT_MTLS_ENDPOINT + patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, + host=expected_host, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=expected_ssl_channel_creds, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", but client_cert_source and default_client_cert_source are None. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None ): - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.ssl_credentials", + new_callable=mock.PropertyMock, + ) as ssl_credentials_mock: + if use_client_cert_env == "false": + is_mtls_mock.return_value = False + ssl_credentials_mock.return_value = None + expected_host = client.DEFAULT_ENDPOINT + expected_ssl_channel_creds = None + else: + is_mtls_mock.return_value = True + ssl_credentials_mock.return_value = mock.Mock() + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_ssl_channel_creds = ( + ssl_credentials_mock.return_value + ) + + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + ssl_channel_credentials=expected_ssl_channel_creds, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + ): + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + is_mtls_mock.return_value = False + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -319,8 +407,7 @@ def test_prediction_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -350,8 +437,7 @@ def test_prediction_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -370,8 +456,7 @@ def test_prediction_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -907,6 +992,21 @@ def test_transport_get_channel(): assert channel +@pytest.mark.parametrize( + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -967,6 +1067,17 @@ def test_prediction_service_base_transport_with_credentials_file(): ) +def test_prediction_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(auth, "default") as adc, mock.patch( + "google.cloud.automl_v1beta1.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport() + adc.assert_called_once() + + def test_prediction_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -1015,179 +1126,110 @@ def test_prediction_service_host_with_port(): def test_prediction_service_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called def test_prediction_service_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_prediction_service_grpc_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], ) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_prediction_service_grpc_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint +def test_prediction_service_transport_channel_mtls_with_client_cert_source( + transport_class, ): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - mock_cred = mock.Mock() - transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], ) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. +def test_prediction_service_transport_channel_mtls_with_adc(transport_class): mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - mock_cred = mock.Mock() - transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_prediction_service_grpc_lro_client(): From e097aa7790d270dbb241e0cc53d4d779ddcaa5a8 Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:54:24 -0700 Subject: [PATCH 07/25] migrate secret manager BUILD file python part to use microgen PiperOrigin-RevId: 332039388 Source-Author: Google APIs Source-Date: Wed Sep 16 10:46:37 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: 877aadc6daf8968e8a1122cf1186623d11d8bd46 Source-Link: https://github.com/googleapis/googleapis/commit/877aadc6daf8968e8a1122cf1186623d11d8bd46 --- google/cloud/automl_v1/__init__.py | 4 ++-- google/cloud/automl_v1beta1/__init__.py | 4 ++-- synth.metadata | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/google/cloud/automl_v1/__init__.py b/google/cloud/automl_v1/__init__.py index b5f76f81..6f22bb65 100644 --- a/google/cloud/automl_v1/__init__.py +++ b/google/cloud/automl_v1/__init__.py @@ -104,6 +104,7 @@ __all__ = ( "AnnotationPayload", "AnnotationSpec", + "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -164,7 +165,6 @@ "OutputConfig", "PredictRequest", "PredictResponse", - "PredictionServiceClient", "TextClassificationDatasetMetadata", "TextClassificationModelMetadata", "TextExtractionAnnotation", @@ -185,5 +185,5 @@ "UndeployModelRequest", "UpdateDatasetRequest", "UpdateModelRequest", - "AutoMlClient", + "PredictionServiceClient", ) diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 30db2703..44f619cb 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -149,6 +149,7 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", + "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -227,7 +228,6 @@ "OutputConfig", "PredictRequest", "PredictResponse", - "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "AutoMlClient", + "PredictionServiceClient", ) diff --git a/synth.metadata b/synth.metadata index a2bb67a2..28cf6035 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "6a18a3c50ffd62de53dd2e44f599d6696580f90b", - "internalRef": "331031262" + "sha": "877aadc6daf8968e8a1122cf1186623d11d8bd46", + "internalRef": "332039388" } }, { From 819f65d8c63aab04556f1b4dfae5ad9b250a1a5b Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:55:10 -0700 Subject: [PATCH 08/25] feat: Add Java microgen rules to imports Source-Author: Mira Leung Source-Date: Mon Sep 21 18:04:02 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: aaac658367398e478d650768344b88acebad50d9 Source-Link: https://github.com/googleapis/googleapis/commit/aaac658367398e478d650768344b88acebad50d9 --- docs/automl_v1beta1/services.rst | 3 + google/cloud/automl_v1/__init__.py | 4 +- .../services/auto_ml/async_client.py | 24 +- .../automl_v1/services/auto_ml/client.py | 70 +- .../services/auto_ml/transports/base.py | 2 +- .../services/auto_ml/transports/grpc.py | 46 +- .../auto_ml/transports/grpc_asyncio.py | 51 +- .../prediction_service/async_client.py | 19 +- .../services/prediction_service/client.py | 70 +- .../prediction_service/transports/base.py | 2 +- .../prediction_service/transports/grpc.py | 46 +- .../transports/grpc_asyncio.py | 51 +- google/cloud/automl_v1beta1/__init__.py | 8 +- .../proto/annotation_payload.proto | 77 -- .../proto/annotation_spec.proto | 48 - .../automl_v1beta1/proto/classification.proto | 216 ---- .../automl_v1beta1/proto/column_spec.proto | 78 -- .../automl_v1beta1/proto/data_items.proto | 221 ---- .../automl_v1beta1/proto/data_stats.proto | 166 --- .../automl_v1beta1/proto/data_types.proto | 105 -- .../cloud/automl_v1beta1/proto/dataset.proto | 96 -- .../automl_v1beta1/proto/detection.proto | 135 -- .../cloud/automl_v1beta1/proto/geometry.proto | 46 - google/cloud/automl_v1beta1/proto/image.proto | 193 --- google/cloud/automl_v1beta1/proto/io.proto | 1132 ----------------- google/cloud/automl_v1beta1/proto/model.proto | 108 -- .../proto/model_evaluation.proto | 116 -- .../automl_v1beta1/proto/operations.proto | 189 --- .../proto/prediction_service.proto | 268 ---- .../cloud/automl_v1beta1/proto/ranges.proto | 35 - .../automl_v1beta1/proto/regression.proto | 44 - .../cloud/automl_v1beta1/proto/service.proto | 800 ------------ .../automl_v1beta1/proto/table_spec.proto | 78 -- .../cloud/automl_v1beta1/proto/tables.proto | 292 ----- .../cloud/automl_v1beta1/proto/temporal.proto | 37 - google/cloud/automl_v1beta1/proto/text.proto | 65 - .../proto/text_extraction.proto | 68 - .../automl_v1beta1/proto/text_segment.proto | 41 - .../automl_v1beta1/proto/text_sentiment.proto | 80 -- .../automl_v1beta1/proto/translation.proto | 69 - google/cloud/automl_v1beta1/proto/video.proto | 48 - .../services/auto_ml/async_client.py | 28 +- .../automl_v1beta1/services/auto_ml/client.py | 70 +- .../services/auto_ml/transports/base.py | 2 +- .../services/auto_ml/transports/grpc.py | 46 +- .../auto_ml/transports/grpc_asyncio.py | 51 +- .../prediction_service/async_client.py | 19 +- .../services/prediction_service/client.py | 70 +- .../prediction_service/transports/base.py | 2 +- .../prediction_service/transports/grpc.py | 46 +- .../transports/grpc_asyncio.py | 51 +- noxfile.py | 34 + synth.metadata | 224 +--- tests/unit/gapic/automl_v1/test_auto_ml.py | 543 ++++---- .../automl_v1/test_prediction_service.py | 494 ++++--- .../unit/gapic/automl_v1beta1/test_auto_ml.py | 601 +++++---- .../automl_v1beta1/test_prediction_service.py | 494 ++++--- 57 files changed, 1300 insertions(+), 6722 deletions(-) delete mode 100644 google/cloud/automl_v1beta1/proto/annotation_payload.proto delete mode 100644 google/cloud/automl_v1beta1/proto/annotation_spec.proto delete mode 100644 google/cloud/automl_v1beta1/proto/classification.proto delete mode 100644 google/cloud/automl_v1beta1/proto/column_spec.proto delete mode 100644 google/cloud/automl_v1beta1/proto/data_items.proto delete mode 100644 google/cloud/automl_v1beta1/proto/data_stats.proto delete mode 100644 google/cloud/automl_v1beta1/proto/data_types.proto delete mode 100644 google/cloud/automl_v1beta1/proto/dataset.proto delete mode 100644 google/cloud/automl_v1beta1/proto/detection.proto delete mode 100644 google/cloud/automl_v1beta1/proto/geometry.proto delete mode 100644 google/cloud/automl_v1beta1/proto/image.proto delete mode 100644 google/cloud/automl_v1beta1/proto/io.proto delete mode 100644 google/cloud/automl_v1beta1/proto/model.proto delete mode 100644 google/cloud/automl_v1beta1/proto/model_evaluation.proto delete mode 100644 google/cloud/automl_v1beta1/proto/operations.proto delete mode 100644 google/cloud/automl_v1beta1/proto/prediction_service.proto delete mode 100644 google/cloud/automl_v1beta1/proto/ranges.proto delete mode 100644 google/cloud/automl_v1beta1/proto/regression.proto delete mode 100644 google/cloud/automl_v1beta1/proto/service.proto delete mode 100644 google/cloud/automl_v1beta1/proto/table_spec.proto delete mode 100644 google/cloud/automl_v1beta1/proto/tables.proto delete mode 100644 google/cloud/automl_v1beta1/proto/temporal.proto delete mode 100644 google/cloud/automl_v1beta1/proto/text.proto delete mode 100644 google/cloud/automl_v1beta1/proto/text_extraction.proto delete mode 100644 google/cloud/automl_v1beta1/proto/text_segment.proto delete mode 100644 google/cloud/automl_v1beta1/proto/text_sentiment.proto delete mode 100644 google/cloud/automl_v1beta1/proto/translation.proto delete mode 100644 google/cloud/automl_v1beta1/proto/video.proto diff --git a/docs/automl_v1beta1/services.rst b/docs/automl_v1beta1/services.rst index 9fa5c54f..787e8566 100644 --- a/docs/automl_v1beta1/services.rst +++ b/docs/automl_v1beta1/services.rst @@ -7,3 +7,6 @@ Services for Google Cloud Automl v1beta1 API .. automodule:: google.cloud.automl_v1beta1.services.prediction_service :members: :inherited-members: +.. automodule:: google.cloud.automl_v1beta1.services.tables + :members: + :inherited-members: diff --git a/google/cloud/automl_v1/__init__.py b/google/cloud/automl_v1/__init__.py index 6f22bb65..b5f76f81 100644 --- a/google/cloud/automl_v1/__init__.py +++ b/google/cloud/automl_v1/__init__.py @@ -104,7 +104,6 @@ __all__ = ( "AnnotationPayload", "AnnotationSpec", - "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -165,6 +164,7 @@ "OutputConfig", "PredictRequest", "PredictResponse", + "PredictionServiceClient", "TextClassificationDatasetMetadata", "TextClassificationModelMetadata", "TextExtractionAnnotation", @@ -185,5 +185,5 @@ "UndeployModelRequest", "UpdateDatasetRequest", "UpdateModelRequest", - "PredictionServiceClient", + "AutoMlClient", ) diff --git a/google/cloud/automl_v1/services/auto_ml/async_client.py b/google/cloud/automl_v1/services/auto_ml/async_client.py index 9dd21f72..2b7f9c5c 100644 --- a/google/cloud/automl_v1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1/services/auto_ml/async_client.py @@ -79,10 +79,9 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT - dataset_path = staticmethod(AutoMlClient.dataset_path) - parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) model_path = staticmethod(AutoMlClient.model_path) - parse_model_path = staticmethod(AutoMlClient.parse_model_path) + + dataset_path = staticmethod(AutoMlClient.dataset_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file @@ -113,19 +112,16 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1/services/auto_ml/client.py b/google/cloud/automl_v1/services/auto_ml/client.py index 6cace8ae..e615ce00 100644 --- a/google/cloud/automl_v1/services/auto_ml/client.py +++ b/google/cloud/automl_v1/services/auto_ml/client.py @@ -16,7 +16,6 @@ # from collections import OrderedDict -from distutils import util import os import re from typing import Callable, Dict, Sequence, Tuple, Type, Union @@ -28,7 +27,6 @@ from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore @@ -217,19 +215,16 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -245,43 +240,25 @@ def __init__( if client_options is None: client_options = ClientOptions.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) - ) - - ssl_credentials = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - is_mtls = True - else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if client_options.api_endpoint is None: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT + client_options.api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT + client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT + has_client_cert_source = ( + client_options.client_cert_source is not None + or mtls.has_default_client_cert_source() + ) + client_options.api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if has_client_cert_source + else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -305,9 +282,10 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=api_endpoint, + host=client_options.api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + api_mtls_endpoint=client_options.api_endpoint, + client_cert_source=client_options.client_cert_source, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1/services/auto_ml/transports/base.py b/google/cloud/automl_v1/services/auto_ml/transports/base.py index b1e12781..5e230105 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth # type: ignore +from google import auth from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py index b957e5cd..100f50f6 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py @@ -15,7 +15,6 @@ # limitations under the License. # -import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -25,6 +24,7 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore + import grpc # type: ignore from google.cloud.automl_v1.types import annotation_spec @@ -78,7 +78,6 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -99,16 +98,14 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -131,11 +128,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -166,23 +158,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) self._stubs = {} # type: Dict[str, Callable] @@ -248,6 +223,13 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py b/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py index 0778c063..39e15a79 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py @@ -15,13 +15,11 @@ # limitations under the License. # -import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -122,7 +120,6 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -144,16 +141,14 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -176,22 +171,12 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -211,23 +196,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) # Run the base constructor. super().__init__( @@ -248,6 +216,13 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/prediction_service/async_client.py b/google/cloud/automl_v1/services/prediction_service/async_client.py index fe1d2226..df141602 100644 --- a/google/cloud/automl_v1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1/services/prediction_service/async_client.py @@ -82,19 +82,16 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1/services/prediction_service/client.py b/google/cloud/automl_v1/services/prediction_service/client.py index d557fd9b..2ccfd9fc 100644 --- a/google/cloud/automl_v1/services/prediction_service/client.py +++ b/google/cloud/automl_v1/services/prediction_service/client.py @@ -16,7 +16,6 @@ # from collections import OrderedDict -from distutils import util import os import re from typing import Callable, Dict, Sequence, Tuple, Type, Union @@ -28,7 +27,6 @@ from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore @@ -163,19 +161,16 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -191,43 +186,25 @@ def __init__( if client_options is None: client_options = ClientOptions.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) - ) - - ssl_credentials = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - is_mtls = True - else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if client_options.api_endpoint is None: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT + client_options.api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT + client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT + has_client_cert_source = ( + client_options.client_cert_source is not None + or mtls.has_default_client_cert_source() + ) + client_options.api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if has_client_cert_source + else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -251,9 +228,10 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=api_endpoint, + host=client_options.api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + api_mtls_endpoint=client_options.api_endpoint, + client_cert_source=client_options.client_cert_source, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1/services/prediction_service/transports/base.py b/google/cloud/automl_v1/services/prediction_service/transports/base.py index f019a8dc..349d8793 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/base.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth # type: ignore +from google import auth from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py index 9a2c8e9b..e4508add 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py @@ -15,7 +15,6 @@ # limitations under the License. # -import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -25,6 +24,7 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore + import grpc # type: ignore from google.cloud.automl_v1.types import prediction_service @@ -61,7 +61,6 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -82,16 +81,14 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -114,11 +111,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -149,23 +141,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) self._stubs = {} # type: Dict[str, Callable] @@ -231,6 +206,13 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py b/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py index eddcb6ab..f92ad264 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py @@ -15,13 +15,11 @@ # limitations under the License. # -import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -105,7 +103,6 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -127,16 +124,14 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -159,22 +154,12 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -194,23 +179,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) # Run the base constructor. super().__init__( @@ -231,6 +199,13 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 44f619cb..904a45aa 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -17,8 +17,8 @@ from .services.auto_ml import AutoMlClient from .services.prediction_service import PredictionServiceClient -from .tables.gcs_client import GcsClient -from .tables.tables_client import TablesClient +from .services.tables.gcs_client import GcsClient +from .services.tables.tables_client import TablesClient from .types.annotation_payload import AnnotationPayload from .types.annotation_spec import AnnotationSpec from .types.classification import ClassificationAnnotation @@ -149,7 +149,6 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", - "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -228,6 +227,7 @@ "OutputConfig", "PredictRequest", "PredictResponse", + "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "PredictionServiceClient", + "AutoMlClient", ) diff --git a/google/cloud/automl_v1beta1/proto/annotation_payload.proto b/google/cloud/automl_v1beta1/proto/annotation_payload.proto deleted file mode 100644 index f62bb269..00000000 --- a/google/cloud/automl_v1beta1/proto/annotation_payload.proto +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/cloud/automl/v1beta1/detection.proto"; -import "google/cloud/automl/v1beta1/tables.proto"; -import "google/cloud/automl/v1beta1/text_extraction.proto"; -import "google/cloud/automl/v1beta1/text_sentiment.proto"; -import "google/cloud/automl/v1beta1/translation.proto"; -import "google/protobuf/any.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Contains annotation information that is relevant to AutoML. -message AnnotationPayload { - // Output only . Additional information about the annotation - // specific to the AutoML domain. - oneof detail { - // Annotation details for translation. - TranslationAnnotation translation = 2; - - // Annotation details for content or image classification. - ClassificationAnnotation classification = 3; - - // Annotation details for image object detection. - ImageObjectDetectionAnnotation image_object_detection = 4; - - // Annotation details for video classification. - // Returned for Video Classification predictions. - VideoClassificationAnnotation video_classification = 9; - - // Annotation details for video object tracking. - VideoObjectTrackingAnnotation video_object_tracking = 8; - - // Annotation details for text extraction. - TextExtractionAnnotation text_extraction = 6; - - // Annotation details for text sentiment. - TextSentimentAnnotation text_sentiment = 7; - - // Annotation details for Tables. - TablesAnnotation tables = 10; - } - - // Output only . The resource ID of the annotation spec that - // this annotation pertains to. The annotation spec comes from either an - // ancestor dataset, or the dataset that was used to train the model in use. - string annotation_spec_id = 1; - - // Output only. The value of - // [display_name][google.cloud.automl.v1beta1.AnnotationSpec.display_name] - // when the model was trained. Because this field returns a value at model - // training time, for different models trained using the same dataset, the - // returned value could be different as model owner could update the - // `display_name` between any two model training. - string display_name = 5; -} diff --git a/google/cloud/automl_v1beta1/proto/annotation_spec.proto b/google/cloud/automl_v1beta1/proto/annotation_spec.proto deleted file mode 100644 index d9df07ee..00000000 --- a/google/cloud/automl_v1beta1/proto/annotation_spec.proto +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A definition of an annotation spec. -message AnnotationSpec { - option (google.api.resource) = { - type: "automl.googleapis.com/AnnotationSpec" - pattern: "projects/{project}/locations/{location}/datasets/{dataset}/annotationSpecs/{annotation_spec}" - }; - - // Output only. Resource name of the annotation spec. - // Form: - // - // 'projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/annotationSpecs/{annotation_spec_id}' - string name = 1; - - // Required. The name of the annotation spec to show in the interface. The name can be - // up to 32 characters long and must match the regexp `[a-zA-Z0-9_]+`. - string display_name = 2; - - // Output only. The number of examples in the parent dataset - // labeled by the annotation spec. - int32 example_count = 9; -} diff --git a/google/cloud/automl_v1beta1/proto/classification.proto b/google/cloud/automl_v1beta1/proto/classification.proto deleted file mode 100644 index 0594d01e..00000000 --- a/google/cloud/automl_v1beta1/proto/classification.proto +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/temporal.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_outer_classname = "ClassificationProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Type of the classification problem. -enum ClassificationType { - // An un-set value of this enum. - CLASSIFICATION_TYPE_UNSPECIFIED = 0; - - // At most one label is allowed per example. - MULTICLASS = 1; - - // Multiple labels are allowed for one example. - MULTILABEL = 2; -} - -// Contains annotation details specific to classification. -message ClassificationAnnotation { - // Output only. A confidence estimate between 0.0 and 1.0. A higher value - // means greater confidence that the annotation is positive. If a user - // approves an annotation as negative or positive, the score value remains - // unchanged. If a user creates an annotation, the score is 0 for negative or - // 1 for positive. - float score = 1; -} - -// Contains annotation details specific to video classification. -message VideoClassificationAnnotation { - // Output only. Expresses the type of video classification. Possible values: - // - // * `segment` - Classification done on a specified by user - // time segment of a video. AnnotationSpec is answered to be present - // in that time segment, if it is present in any part of it. The video - // ML model evaluations are done only for this type of classification. - // - // * `shot`- Shot-level classification. - // AutoML Video Intelligence determines the boundaries - // for each camera shot in the entire segment of the video that user - // specified in the request configuration. AutoML Video Intelligence - // then returns labels and their confidence scores for each detected - // shot, along with the start and end time of the shot. - // WARNING: Model evaluation is not done for this classification type, - // the quality of it depends on training data, but there are no - // metrics provided to describe that quality. - // - // * `1s_interval` - AutoML Video Intelligence returns labels and their - // confidence scores for each second of the entire segment of the video - // that user specified in the request configuration. - // WARNING: Model evaluation is not done for this classification type, - // the quality of it depends on training data, but there are no - // metrics provided to describe that quality. - string type = 1; - - // Output only . The classification details of this annotation. - ClassificationAnnotation classification_annotation = 2; - - // Output only . The time segment of the video to which the - // annotation applies. - TimeSegment time_segment = 3; -} - -// Model evaluation metrics for classification problems. -// Note: For Video Classification this metrics only describe quality of the -// Video Classification predictions of "segment_classification" type. -message ClassificationEvaluationMetrics { - // Metrics for a single confidence threshold. - message ConfidenceMetricsEntry { - // Output only. Metrics are computed with an assumption that the model - // never returns predictions with score lower than this value. - float confidence_threshold = 1; - - // Output only. Metrics are computed with an assumption that the model - // always returns at most this many predictions (ordered by their score, - // descendingly), but they all still need to meet the confidence_threshold. - int32 position_threshold = 14; - - // Output only. Recall (True Positive Rate) for the given confidence - // threshold. - float recall = 2; - - // Output only. Precision for the given confidence threshold. - float precision = 3; - - // Output only. False Positive Rate for the given confidence threshold. - float false_positive_rate = 8; - - // Output only. The harmonic mean of recall and precision. - float f1_score = 4; - - // Output only. The Recall (True Positive Rate) when only considering the - // label that has the highest prediction score and not below the confidence - // threshold for each example. - float recall_at1 = 5; - - // Output only. The precision when only considering the label that has the - // highest prediction score and not below the confidence threshold for each - // example. - float precision_at1 = 6; - - // Output only. The False Positive Rate when only considering the label that - // has the highest prediction score and not below the confidence threshold - // for each example. - float false_positive_rate_at1 = 9; - - // Output only. The harmonic mean of [recall_at1][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfidenceMetricsEntry.recall_at1] and [precision_at1][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfidenceMetricsEntry.precision_at1]. - float f1_score_at1 = 7; - - // Output only. The number of model created labels that match a ground truth - // label. - int64 true_positive_count = 10; - - // Output only. The number of model created labels that do not match a - // ground truth label. - int64 false_positive_count = 11; - - // Output only. The number of ground truth labels that are not matched - // by a model created label. - int64 false_negative_count = 12; - - // Output only. The number of labels that were not created by the model, - // but if they would, they would not match a ground truth label. - int64 true_negative_count = 13; - } - - // Confusion matrix of the model running the classification. - message ConfusionMatrix { - // Output only. A row in the confusion matrix. - message Row { - // Output only. Value of the specific cell in the confusion matrix. - // The number of values each row has (i.e. the length of the row) is equal - // to the length of the `annotation_spec_id` field or, if that one is not - // populated, length of the [display_name][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfusionMatrix.display_name] field. - repeated int32 example_count = 1; - } - - // Output only. IDs of the annotation specs used in the confusion matrix. - // For Tables CLASSIFICATION - // - // [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] - // only list of [annotation_spec_display_name-s][] is populated. - repeated string annotation_spec_id = 1; - - // Output only. Display name of the annotation specs used in the confusion - // matrix, as they were at the moment of the evaluation. For Tables - // CLASSIFICATION - // - // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type], - // distinct values of the target column at the moment of the model - // evaluation are populated here. - repeated string display_name = 3; - - // Output only. Rows in the confusion matrix. The number of rows is equal to - // the size of `annotation_spec_id`. - // `row[i].example_count[j]` is the number of examples that have ground - // truth of the `annotation_spec_id[i]` and are predicted as - // `annotation_spec_id[j]` by the model being evaluated. - repeated Row row = 2; - } - - // Output only. The Area Under Precision-Recall Curve metric. Micro-averaged - // for the overall evaluation. - float au_prc = 1; - - // Output only. The Area Under Precision-Recall Curve metric based on priors. - // Micro-averaged for the overall evaluation. - // Deprecated. - float base_au_prc = 2 [deprecated = true]; - - // Output only. The Area Under Receiver Operating Characteristic curve metric. - // Micro-averaged for the overall evaluation. - float au_roc = 6; - - // Output only. The Log Loss metric. - float log_loss = 7; - - // Output only. Metrics for each confidence_threshold in - // 0.00,0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 and - // position_threshold = INT32_MAX_VALUE. - // ROC and precision-recall curves, and other aggregated metrics are derived - // from them. The confidence metrics entries may also be supplied for - // additional values of position_threshold, but from these no aggregated - // metrics are computed. - repeated ConfidenceMetricsEntry confidence_metrics_entry = 3; - - // Output only. Confusion matrix of the evaluation. - // Only set for MULTICLASS classification problems where number - // of labels is no more than 10. - // Only set for model level evaluation, not for evaluation per label. - ConfusionMatrix confusion_matrix = 4; - - // Output only. The annotation spec ids used for this evaluation. - repeated string annotation_spec_id = 5; -} diff --git a/google/cloud/automl_v1beta1/proto/column_spec.proto b/google/cloud/automl_v1beta1/proto/column_spec.proto deleted file mode 100644 index 03389b8a..00000000 --- a/google/cloud/automl_v1beta1/proto/column_spec.proto +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/data_stats.proto"; -import "google/cloud/automl/v1beta1/data_types.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A representation of a column in a relational table. When listing them, column specs are returned in the same order in which they were -// given on import . -// Used by: -// * Tables -message ColumnSpec { - option (google.api.resource) = { - type: "automl.googleapis.com/ColumnSpec" - pattern: "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}" - }; - - // Identifies the table's column, and its correlation with the column this - // ColumnSpec describes. - message CorrelatedColumn { - // The column_spec_id of the correlated column, which belongs to the same - // table as the in-context column. - string column_spec_id = 1; - - // Correlation between this and the in-context column. - CorrelationStats correlation_stats = 2; - } - - // Output only. The resource name of the column specs. - // Form: - // - // `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/tableSpecs/{table_spec_id}/columnSpecs/{column_spec_id}` - string name = 1; - - // The data type of elements stored in the column. - DataType data_type = 2; - - // Output only. The name of the column to show in the interface. The name can - // be up to 100 characters long and can consist only of ASCII Latin letters - // A-Z and a-z, ASCII digits 0-9, underscores(_), and forward slashes(/), and - // must start with a letter or a digit. - string display_name = 3; - - // Output only. Stats of the series of values in the column. - // This field may be stale, see the ancestor's - // Dataset.tables_dataset_metadata.stats_update_time field - // for the timestamp at which these stats were last updated. - DataStats data_stats = 4; - - // Deprecated. - repeated CorrelatedColumn top_correlated_columns = 5; - - // Used to perform consistent read-modify-write updates. If not set, a blind - // "overwrite" update happens. - string etag = 6; -} diff --git a/google/cloud/automl_v1beta1/proto/data_items.proto b/google/cloud/automl_v1beta1/proto/data_items.proto deleted file mode 100644 index 9b9187ad..00000000 --- a/google/cloud/automl_v1beta1/proto/data_items.proto +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/geometry.proto"; -import "google/cloud/automl/v1beta1/io.proto"; -import "google/cloud/automl/v1beta1/temporal.proto"; -import "google/cloud/automl/v1beta1/text_segment.proto"; -import "google/protobuf/any.proto"; -import "google/protobuf/duration.proto"; -import "google/protobuf/struct.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A representation of an image. -// Only images up to 30MB in size are supported. -message Image { - // Input only. The data representing the image. - // For Predict calls [image_bytes][google.cloud.automl.v1beta1.Image.image_bytes] must be set, as other options are not - // currently supported by prediction API. You can read the contents of an - // uploaded image by using the [content_uri][google.cloud.automl.v1beta1.Image.content_uri] field. - oneof data { - // Image content represented as a stream of bytes. - // Note: As with all `bytes` fields, protobuffers use a pure binary - // representation, whereas JSON representations use base64. - bytes image_bytes = 1; - - // An input config specifying the content of the image. - InputConfig input_config = 6; - } - - // Output only. HTTP URI to the thumbnail image. - string thumbnail_uri = 4; -} - -// A representation of a text snippet. -message TextSnippet { - // Required. The content of the text snippet as a string. Up to 250000 - // characters long. - string content = 1; - - // Optional. The format of [content][google.cloud.automl.v1beta1.TextSnippet.content]. Currently the only two allowed - // values are "text/html" and "text/plain". If left blank, the format is - // automatically determined from the type of the uploaded [content][google.cloud.automl.v1beta1.TextSnippet.content]. - string mime_type = 2; - - // Output only. HTTP URI where you can download the content. - string content_uri = 4; -} - -// Message that describes dimension of a document. -message DocumentDimensions { - // Unit of the document dimension. - enum DocumentDimensionUnit { - // Should not be used. - DOCUMENT_DIMENSION_UNIT_UNSPECIFIED = 0; - - // Document dimension is measured in inches. - INCH = 1; - - // Document dimension is measured in centimeters. - CENTIMETER = 2; - - // Document dimension is measured in points. 72 points = 1 inch. - POINT = 3; - } - - // Unit of the dimension. - DocumentDimensionUnit unit = 1; - - // Width value of the document, works together with the unit. - float width = 2; - - // Height value of the document, works together with the unit. - float height = 3; -} - -// A structured text document e.g. a PDF. -message Document { - // Describes the layout information of a [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the document. - message Layout { - // The type of TextSegment in the context of the original document. - enum TextSegmentType { - // Should not be used. - TEXT_SEGMENT_TYPE_UNSPECIFIED = 0; - - // The text segment is a token. e.g. word. - TOKEN = 1; - - // The text segment is a paragraph. - PARAGRAPH = 2; - - // The text segment is a form field. - FORM_FIELD = 3; - - // The text segment is the name part of a form field. It will be treated - // as child of another FORM_FIELD TextSegment if its span is subspan of - // another TextSegment with type FORM_FIELD. - FORM_FIELD_NAME = 4; - - // The text segment is the text content part of a form field. It will be - // treated as child of another FORM_FIELD TextSegment if its span is - // subspan of another TextSegment with type FORM_FIELD. - FORM_FIELD_CONTENTS = 5; - - // The text segment is a whole table, including headers, and all rows. - TABLE = 6; - - // The text segment is a table's headers. It will be treated as child of - // another TABLE TextSegment if its span is subspan of another TextSegment - // with type TABLE. - TABLE_HEADER = 7; - - // The text segment is a row in table. It will be treated as child of - // another TABLE TextSegment if its span is subspan of another TextSegment - // with type TABLE. - TABLE_ROW = 8; - - // The text segment is a cell in table. It will be treated as child of - // another TABLE_ROW TextSegment if its span is subspan of another - // TextSegment with type TABLE_ROW. - TABLE_CELL = 9; - } - - // Text Segment that represents a segment in - // [document_text][google.cloud.automl.v1beta1.Document.document_text]. - TextSegment text_segment = 1; - - // Page number of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the original document, starts - // from 1. - int32 page_number = 2; - - // The position of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the page. - // Contains exactly 4 - // - // [normalized_vertices][google.cloud.automl.v1beta1.BoundingPoly.normalized_vertices] - // and they are connected by edges in the order provided, which will - // represent a rectangle parallel to the frame. The - // [NormalizedVertex-s][google.cloud.automl.v1beta1.NormalizedVertex] are - // relative to the page. - // Coordinates are based on top-left as point (0,0). - BoundingPoly bounding_poly = 3; - - // The type of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in document. - TextSegmentType text_segment_type = 4; - } - - // An input config specifying the content of the document. - DocumentInputConfig input_config = 1; - - // The plain text version of this document. - TextSnippet document_text = 2; - - // Describes the layout of the document. - // Sorted by [page_number][]. - repeated Layout layout = 3; - - // The dimensions of the page in the document. - DocumentDimensions document_dimensions = 4; - - // Number of pages in the document. - int32 page_count = 5; -} - -// A representation of a row in a relational table. -message Row { - // The resource IDs of the column specs describing the columns of the row. - // If set must contain, but possibly in a different order, all input - // feature - // - // [column_spec_ids][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] - // of the Model this row is being passed to. - // Note: The below `values` field must match order of this field, if this - // field is set. - repeated string column_spec_ids = 2; - - // Required. The values of the row cells, given in the same order as the - // column_spec_ids, or, if not set, then in the same order as input - // feature - // - // [column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] - // of the Model this row is being passed to. - repeated google.protobuf.Value values = 3; -} - -// Example data used for training or prediction. -message ExamplePayload { - // Required. Input only. The example data. - oneof payload { - // Example image. - Image image = 1; - - // Example text. - TextSnippet text_snippet = 2; - - // Example document. - Document document = 4; - - // Example relational table row. - Row row = 3; - } -} diff --git a/google/cloud/automl_v1beta1/proto/data_stats.proto b/google/cloud/automl_v1beta1/proto/data_stats.proto deleted file mode 100644 index c13a5d45..00000000 --- a/google/cloud/automl_v1beta1/proto/data_stats.proto +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// The data statistics of a series of values that share the same DataType. -message DataStats { - // The data statistics specific to a DataType. - oneof stats { - // The statistics for FLOAT64 DataType. - Float64Stats float64_stats = 3; - - // The statistics for STRING DataType. - StringStats string_stats = 4; - - // The statistics for TIMESTAMP DataType. - TimestampStats timestamp_stats = 5; - - // The statistics for ARRAY DataType. - ArrayStats array_stats = 6; - - // The statistics for STRUCT DataType. - StructStats struct_stats = 7; - - // The statistics for CATEGORY DataType. - CategoryStats category_stats = 8; - } - - // The number of distinct values. - int64 distinct_value_count = 1; - - // The number of values that are null. - int64 null_value_count = 2; - - // The number of values that are valid. - int64 valid_value_count = 9; -} - -// The data statistics of a series of FLOAT64 values. -message Float64Stats { - // A bucket of a histogram. - message HistogramBucket { - // The minimum value of the bucket, inclusive. - double min = 1; - - // The maximum value of the bucket, exclusive unless max = `"Infinity"`, in - // which case it's inclusive. - double max = 2; - - // The number of data values that are in the bucket, i.e. are between - // min and max values. - int64 count = 3; - } - - // The mean of the series. - double mean = 1; - - // The standard deviation of the series. - double standard_deviation = 2; - - // Ordered from 0 to k k-quantile values of the data series of n values. - // The value at index i is, approximately, the i*n/k-th smallest value in the - // series; for i = 0 and i = k these are, respectively, the min and max - // values. - repeated double quantiles = 3; - - // Histogram buckets of the data series. Sorted by the min value of the - // bucket, ascendingly, and the number of the buckets is dynamically - // generated. The buckets are non-overlapping and completely cover whole - // FLOAT64 range with min of first bucket being `"-Infinity"`, and max of - // the last one being `"Infinity"`. - repeated HistogramBucket histogram_buckets = 4; -} - -// The data statistics of a series of STRING values. -message StringStats { - // The statistics of a unigram. - message UnigramStats { - // The unigram. - string value = 1; - - // The number of occurrences of this unigram in the series. - int64 count = 2; - } - - // The statistics of the top 20 unigrams, ordered by - // [count][google.cloud.automl.v1beta1.StringStats.UnigramStats.count]. - repeated UnigramStats top_unigram_stats = 1; -} - -// The data statistics of a series of TIMESTAMP values. -message TimestampStats { - // Stats split by a defined in context granularity. - message GranularStats { - // A map from granularity key to example count for that key. - // E.g. for hour_of_day `13` means 1pm, or for month_of_year `5` means May). - map buckets = 1; - } - - // The string key is the pre-defined granularity. Currently supported: - // hour_of_day, day_of_week, month_of_year. - // Granularities finer that the granularity of timestamp data are not - // populated (e.g. if timestamps are at day granularity, then hour_of_day - // is not populated). - map granular_stats = 1; -} - -// The data statistics of a series of ARRAY values. -message ArrayStats { - // Stats of all the values of all arrays, as if they were a single long - // series of data. The type depends on the element type of the array. - DataStats member_stats = 2; -} - -// The data statistics of a series of STRUCT values. -message StructStats { - // Map from a field name of the struct to data stats aggregated over series - // of all data in that field across all the structs. - map field_stats = 1; -} - -// The data statistics of a series of CATEGORY values. -message CategoryStats { - // The statistics of a single CATEGORY value. - message SingleCategoryStats { - // The CATEGORY value. - string value = 1; - - // The number of occurrences of this value in the series. - int64 count = 2; - } - - // The statistics of the top 20 CATEGORY values, ordered by - // - // [count][google.cloud.automl.v1beta1.CategoryStats.SingleCategoryStats.count]. - repeated SingleCategoryStats top_category_stats = 1; -} - -// A correlation statistics between two series of DataType values. The series -// may have differing DataType-s, but within a single series the DataType must -// be the same. -message CorrelationStats { - // The correlation value using the Cramer's V measure. - double cramers_v = 1; -} diff --git a/google/cloud/automl_v1beta1/proto/data_types.proto b/google/cloud/automl_v1beta1/proto/data_types.proto deleted file mode 100644 index 6f77f56b..00000000 --- a/google/cloud/automl_v1beta1/proto/data_types.proto +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// `TypeCode` is used as a part of -// [DataType][google.cloud.automl.v1beta1.DataType]. -enum TypeCode { - // Not specified. Should not be used. - TYPE_CODE_UNSPECIFIED = 0; - - // Encoded as `number`, or the strings `"NaN"`, `"Infinity"`, or - // `"-Infinity"`. - FLOAT64 = 3; - - // Must be between 0AD and 9999AD. Encoded as `string` according to - // [time_format][google.cloud.automl.v1beta1.DataType.time_format], or, if - // that format is not set, then in RFC 3339 `date-time` format, where - // `time-offset` = `"Z"` (e.g. 1985-04-12T23:20:50.52Z). - TIMESTAMP = 4; - - // Encoded as `string`. - STRING = 6; - - // Encoded as `list`, where the list elements are represented according to - // - // [list_element_type][google.cloud.automl.v1beta1.DataType.list_element_type]. - ARRAY = 8; - - // Encoded as `struct`, where field values are represented according to - // [struct_type][google.cloud.automl.v1beta1.DataType.struct_type]. - STRUCT = 9; - - // Values of this type are not further understood by AutoML, - // e.g. AutoML is unable to tell the order of values (as it could with - // FLOAT64), or is unable to say if one value contains another (as it - // could with STRING). - // Encoded as `string` (bytes should be base64-encoded, as described in RFC - // 4648, section 4). - CATEGORY = 10; -} - -// Indicated the type of data that can be stored in a structured data entity -// (e.g. a table). -message DataType { - // Details of DataType-s that need additional specification. - oneof details { - // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [ARRAY][google.cloud.automl.v1beta1.TypeCode.ARRAY], - // then `list_element_type` is the type of the elements. - DataType list_element_type = 2; - - // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [STRUCT][google.cloud.automl.v1beta1.TypeCode.STRUCT], then `struct_type` - // provides type information for the struct's fields. - StructType struct_type = 3; - - // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [TIMESTAMP][google.cloud.automl.v1beta1.TypeCode.TIMESTAMP] - // then `time_format` provides the format in which that time field is - // expressed. The time_format must either be one of: - // * `UNIX_SECONDS` - // * `UNIX_MILLISECONDS` - // * `UNIX_MICROSECONDS` - // * `UNIX_NANOSECONDS` - // (for respectively number of seconds, milliseconds, microseconds and - // nanoseconds since start of the Unix epoch); - // or be written in `strftime` syntax. If time_format is not set, then the - // default format as described on the type_code is used. - string time_format = 5; - } - - // Required. The [TypeCode][google.cloud.automl.v1beta1.TypeCode] for this type. - TypeCode type_code = 1; - - // If true, this DataType can also be `NULL`. In .CSV files `NULL` value is - // expressed as an empty string. - bool nullable = 4; -} - -// `StructType` defines the DataType-s of a [STRUCT][google.cloud.automl.v1beta1.TypeCode.STRUCT] type. -message StructType { - // Unordered map of struct field names to their data types. - // Fields cannot be added or removed via Update. Their names and - // data types are still mutable. - map fields = 1; -} diff --git a/google/cloud/automl_v1beta1/proto/dataset.proto b/google/cloud/automl_v1beta1/proto/dataset.proto deleted file mode 100644 index 8d1b8d93..00000000 --- a/google/cloud/automl_v1beta1/proto/dataset.proto +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/image.proto"; -import "google/cloud/automl/v1beta1/tables.proto"; -import "google/cloud/automl/v1beta1/text.proto"; -import "google/cloud/automl/v1beta1/translation.proto"; -import "google/cloud/automl/v1beta1/video.proto"; -import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A workspace for solving a single, particular machine learning (ML) problem. -// A workspace contains examples that may be annotated. -message Dataset { - option (google.api.resource) = { - type: "automl.googleapis.com/Dataset" - pattern: "projects/{project}/locations/{location}/datasets/{dataset}" - }; - - // Required. - // The dataset metadata that is specific to the problem type. - oneof dataset_metadata { - // Metadata for a dataset used for translation. - TranslationDatasetMetadata translation_dataset_metadata = 23; - - // Metadata for a dataset used for image classification. - ImageClassificationDatasetMetadata image_classification_dataset_metadata = 24; - - // Metadata for a dataset used for text classification. - TextClassificationDatasetMetadata text_classification_dataset_metadata = 25; - - // Metadata for a dataset used for image object detection. - ImageObjectDetectionDatasetMetadata image_object_detection_dataset_metadata = 26; - - // Metadata for a dataset used for video classification. - VideoClassificationDatasetMetadata video_classification_dataset_metadata = 31; - - // Metadata for a dataset used for video object tracking. - VideoObjectTrackingDatasetMetadata video_object_tracking_dataset_metadata = 29; - - // Metadata for a dataset used for text extraction. - TextExtractionDatasetMetadata text_extraction_dataset_metadata = 28; - - // Metadata for a dataset used for text sentiment. - TextSentimentDatasetMetadata text_sentiment_dataset_metadata = 30; - - // Metadata for a dataset used for Tables. - TablesDatasetMetadata tables_dataset_metadata = 33; - } - - // Output only. The resource name of the dataset. - // Form: `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}` - string name = 1; - - // Required. The name of the dataset to show in the interface. The name can be - // up to 32 characters long and can consist only of ASCII Latin letters A-Z - // and a-z, underscores - // (_), and ASCII digits 0-9. - string display_name = 2; - - // User-provided description of the dataset. The description can be up to - // 25000 characters long. - string description = 3; - - // Output only. The number of examples in the dataset. - int32 example_count = 21; - - // Output only. Timestamp when this dataset was created. - google.protobuf.Timestamp create_time = 14; - - // Used to perform consistent read-modify-write updates. If not set, a blind - // "overwrite" update happens. - string etag = 17; -} diff --git a/google/cloud/automl_v1beta1/proto/detection.proto b/google/cloud/automl_v1beta1/proto/detection.proto deleted file mode 100644 index c5864e20..00000000 --- a/google/cloud/automl_v1beta1/proto/detection.proto +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/geometry.proto"; -import "google/protobuf/duration.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Annotation details for image object detection. -message ImageObjectDetectionAnnotation { - // Output only. The rectangle representing the object location. - BoundingPoly bounding_box = 1; - - // Output only. The confidence that this annotation is positive for the parent example, - // value in [0, 1], higher means higher positivity confidence. - float score = 2; -} - -// Annotation details for video object tracking. -message VideoObjectTrackingAnnotation { - // Optional. The instance of the object, expressed as a positive integer. Used to tell - // apart objects of the same type (i.e. AnnotationSpec) when multiple are - // present on a single example. - // NOTE: Instance ID prediction quality is not a part of model evaluation and - // is done as best effort. Especially in cases when an entity goes - // off-screen for a longer time (minutes), when it comes back it may be given - // a new instance ID. - string instance_id = 1; - - // Required. A time (frame) of a video to which this annotation pertains. - // Represented as the duration since the video's start. - google.protobuf.Duration time_offset = 2; - - // Required. The rectangle representing the object location on the frame (i.e. - // at the time_offset of the video). - BoundingPoly bounding_box = 3; - - // Output only. The confidence that this annotation is positive for the video at - // the time_offset, value in [0, 1], higher means higher positivity - // confidence. For annotations created by the user the score is 1. When - // user approves an annotation, the original float score is kept (and not - // changed to 1). - float score = 4; -} - -// Bounding box matching model metrics for a single intersection-over-union -// threshold and multiple label match confidence thresholds. -message BoundingBoxMetricsEntry { - // Metrics for a single confidence threshold. - message ConfidenceMetricsEntry { - // Output only. The confidence threshold value used to compute the metrics. - float confidence_threshold = 1; - - // Output only. Recall under the given confidence threshold. - float recall = 2; - - // Output only. Precision under the given confidence threshold. - float precision = 3; - - // Output only. The harmonic mean of recall and precision. - float f1_score = 4; - } - - // Output only. The intersection-over-union threshold value used to compute - // this metrics entry. - float iou_threshold = 1; - - // Output only. The mean average precision, most often close to au_prc. - float mean_average_precision = 2; - - // Output only. Metrics for each label-match confidence_threshold from - // 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99. Precision-recall curve is - // derived from them. - repeated ConfidenceMetricsEntry confidence_metrics_entries = 3; -} - -// Model evaluation metrics for image object detection problems. -// Evaluates prediction quality of labeled bounding boxes. -message ImageObjectDetectionEvaluationMetrics { - // Output only. The total number of bounding boxes (i.e. summed over all - // images) the ground truth used to create this evaluation had. - int32 evaluated_bounding_box_count = 1; - - // Output only. The bounding boxes match metrics for each - // Intersection-over-union threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 - // and each label confidence threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 - // pair. - repeated BoundingBoxMetricsEntry bounding_box_metrics_entries = 2; - - // Output only. The single metric for bounding boxes evaluation: - // the mean_average_precision averaged over all bounding_box_metrics_entries. - float bounding_box_mean_average_precision = 3; -} - -// Model evaluation metrics for video object tracking problems. -// Evaluates prediction quality of both labeled bounding boxes and labeled -// tracks (i.e. series of bounding boxes sharing same label and instance ID). -message VideoObjectTrackingEvaluationMetrics { - // Output only. The number of video frames used to create this evaluation. - int32 evaluated_frame_count = 1; - - // Output only. The total number of bounding boxes (i.e. summed over all - // frames) the ground truth used to create this evaluation had. - int32 evaluated_bounding_box_count = 2; - - // Output only. The bounding boxes match metrics for each - // Intersection-over-union threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 - // and each label confidence threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 - // pair. - repeated BoundingBoxMetricsEntry bounding_box_metrics_entries = 4; - - // Output only. The single metric for bounding boxes evaluation: - // the mean_average_precision averaged over all bounding_box_metrics_entries. - float bounding_box_mean_average_precision = 6; -} diff --git a/google/cloud/automl_v1beta1/proto/geometry.proto b/google/cloud/automl_v1beta1/proto/geometry.proto deleted file mode 100644 index d5654aac..00000000 --- a/google/cloud/automl_v1beta1/proto/geometry.proto +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A vertex represents a 2D point in the image. -// The normalized vertex coordinates are between 0 to 1 fractions relative to -// the original plane (image, video). E.g. if the plane (e.g. whole image) would -// have size 10 x 20 then a point with normalized coordinates (0.1, 0.3) would -// be at the position (1, 6) on that plane. -message NormalizedVertex { - // Required. Horizontal coordinate. - float x = 1; - - // Required. Vertical coordinate. - float y = 2; -} - -// A bounding polygon of a detected object on a plane. -// On output both vertices and normalized_vertices are provided. -// The polygon is formed by connecting vertices in the order they are listed. -message BoundingPoly { - // Output only . The bounding polygon normalized vertices. - repeated NormalizedVertex normalized_vertices = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/image.proto b/google/cloud/automl_v1beta1/proto/image.proto deleted file mode 100644 index 960eaeb0..00000000 --- a/google/cloud/automl_v1beta1/proto/image.proto +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/annotation_spec.proto"; -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "ImageProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Dataset metadata that is specific to image classification. -message ImageClassificationDatasetMetadata { - // Required. Type of the classification problem. - ClassificationType classification_type = 1; -} - -// Dataset metadata specific to image object detection. -message ImageObjectDetectionDatasetMetadata { - -} - -// Model metadata for image classification. -message ImageClassificationModelMetadata { - // Optional. The ID of the `base` model. If it is specified, the new model - // will be created based on the `base` model. Otherwise, the new model will be - // created from scratch. The `base` model must be in the same - // `project` and `location` as the new model to create, and have the same - // `model_type`. - string base_model_id = 1; - - // Required. The train budget of creating this model, expressed in hours. The - // actual `train_cost` will be equal or less than this value. - int64 train_budget = 2; - - // Output only. The actual train cost of creating this model, expressed in - // hours. If this model is created from a `base` model, the train cost used - // to create the `base` model are not included. - int64 train_cost = 3; - - // Output only. The reason that this create model operation stopped, - // e.g. `BUDGET_REACHED`, `MODEL_CONVERGED`. - string stop_reason = 5; - - // Optional. Type of the model. The available values are: - // * `cloud` - Model to be used via prediction calls to AutoML API. - // This is the default value. - // * `mobile-low-latency-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device - // with TensorFlow afterwards. Expected to have low latency, but - // may have lower prediction quality than other models. - // * `mobile-versatile-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device - // with TensorFlow afterwards. - // * `mobile-high-accuracy-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device - // with TensorFlow afterwards. Expected to have a higher - // latency, but should also have a higher prediction quality - // than other models. - // * `mobile-core-ml-low-latency-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with Core - // ML afterwards. Expected to have low latency, but may have - // lower prediction quality than other models. - // * `mobile-core-ml-versatile-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with Core - // ML afterwards. - // * `mobile-core-ml-high-accuracy-1` - A model that, in addition to - // providing prediction via AutoML API, can also be exported - // (see [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with - // Core ML afterwards. Expected to have a higher latency, but - // should also have a higher prediction quality than other - // models. - string model_type = 7; - - // Output only. An approximate number of online prediction QPS that can - // be supported by this model per each node on which it is deployed. - double node_qps = 13; - - // Output only. The number of nodes this model is deployed on. A node is an - // abstraction of a machine resource, which can handle online prediction QPS - // as given in the node_qps field. - int64 node_count = 14; -} - -// Model metadata specific to image object detection. -message ImageObjectDetectionModelMetadata { - // Optional. Type of the model. The available values are: - // * `cloud-high-accuracy-1` - (default) A model to be used via prediction - // calls to AutoML API. Expected to have a higher latency, but - // should also have a higher prediction quality than other - // models. - // * `cloud-low-latency-1` - A model to be used via prediction - // calls to AutoML API. Expected to have low latency, but may - // have lower prediction quality than other models. - // * `mobile-low-latency-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device - // with TensorFlow afterwards. Expected to have low latency, but - // may have lower prediction quality than other models. - // * `mobile-versatile-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device - // with TensorFlow afterwards. - // * `mobile-high-accuracy-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device - // with TensorFlow afterwards. Expected to have a higher - // latency, but should also have a higher prediction quality - // than other models. - string model_type = 1; - - // Output only. The number of nodes this model is deployed on. A node is an - // abstraction of a machine resource, which can handle online prediction QPS - // as given in the qps_per_node field. - int64 node_count = 3; - - // Output only. An approximate number of online prediction QPS that can - // be supported by this model per each node on which it is deployed. - double node_qps = 4; - - // Output only. The reason that this create model operation stopped, - // e.g. `BUDGET_REACHED`, `MODEL_CONVERGED`. - string stop_reason = 5; - - // The train budget of creating this model, expressed in milli node - // hours i.e. 1,000 value in this field means 1 node hour. The actual - // `train_cost` will be equal or less than this value. If further model - // training ceases to provide any improvements, it will stop without using - // full budget and the stop_reason will be `MODEL_CONVERGED`. - // Note, node_hour = actual_hour * number_of_nodes_invovled. - // For model type `cloud-high-accuracy-1`(default) and `cloud-low-latency-1`, - // the train budget must be between 20,000 and 900,000 milli node hours, - // inclusive. The default value is 216, 000 which represents one day in - // wall time. - // For model type `mobile-low-latency-1`, `mobile-versatile-1`, - // `mobile-high-accuracy-1`, `mobile-core-ml-low-latency-1`, - // `mobile-core-ml-versatile-1`, `mobile-core-ml-high-accuracy-1`, the train - // budget must be between 1,000 and 100,000 milli node hours, inclusive. - // The default value is 24, 000 which represents one day in wall time. - int64 train_budget_milli_node_hours = 6; - - // Output only. The actual train cost of creating this model, expressed in - // milli node hours, i.e. 1,000 value in this field means 1 node hour. - // Guaranteed to not exceed the train budget. - int64 train_cost_milli_node_hours = 7; -} - -// Model deployment metadata specific to Image Classification. -message ImageClassificationModelDeploymentMetadata { - // Input only. The number of nodes to deploy the model on. A node is an - // abstraction of a machine resource, which can handle online prediction QPS - // as given in the model's - // - // [node_qps][google.cloud.automl.v1beta1.ImageClassificationModelMetadata.node_qps]. - // Must be between 1 and 100, inclusive on both ends. - int64 node_count = 1; -} - -// Model deployment metadata specific to Image Object Detection. -message ImageObjectDetectionModelDeploymentMetadata { - // Input only. The number of nodes to deploy the model on. A node is an - // abstraction of a machine resource, which can handle online prediction QPS - // as given in the model's - // - // [qps_per_node][google.cloud.automl.v1beta1.ImageObjectDetectionModelMetadata.qps_per_node]. - // Must be between 1 and 100, inclusive on both ends. - int64 node_count = 1; -} diff --git a/google/cloud/automl_v1beta1/proto/io.proto b/google/cloud/automl_v1beta1/proto/io.proto deleted file mode 100644 index a9979383..00000000 --- a/google/cloud/automl_v1beta1/proto/io.proto +++ /dev/null @@ -1,1132 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Input configuration for ImportData Action. -// -// The format of input depends on dataset_metadata the Dataset into which -// the import is happening has. As input source the -// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] -// is expected, unless specified otherwise. Additionally any input .CSV file -// by itself must be 100MB or smaller, unless specified otherwise. -// If an "example" file (that is, image, video etc.) with identical content -// (even if it had different GCS_FILE_PATH) is mentioned multiple times, then -// its label, bounding boxes etc. are appended. The same file should be always -// provided with the same ML_USE and GCS_FILE_PATH, if it is not, then -// these values are nondeterministically selected from the given ones. -// -// The formats are represented in EBNF with commas being literal and with -// non-terminal symbols defined near the end of this comment. The formats are: -// -// * For Image Classification: -// CSV file(s) with each line in format: -// ML_USE,GCS_FILE_PATH,LABEL,LABEL,... -// GCS_FILE_PATH leads to image of up to 30MB in size. Supported -// extensions: .JPEG, .GIF, .PNG, .WEBP, .BMP, .TIFF, .ICO -// For MULTICLASS classification type, at most one LABEL is allowed -// per image. If an image has not yet been labeled, then it should be -// mentioned just once with no LABEL. -// Some sample rows: -// TRAIN,gs://folder/image1.jpg,daisy -// TEST,gs://folder/image2.jpg,dandelion,tulip,rose -// UNASSIGNED,gs://folder/image3.jpg,daisy -// UNASSIGNED,gs://folder/image4.jpg -// -// * For Image Object Detection: -// CSV file(s) with each line in format: -// ML_USE,GCS_FILE_PATH,(LABEL,BOUNDING_BOX | ,,,,,,,) -// GCS_FILE_PATH leads to image of up to 30MB in size. Supported -// extensions: .JPEG, .GIF, .PNG. -// Each image is assumed to be exhaustively labeled. The minimum -// allowed BOUNDING_BOX edge length is 0.01, and no more than 500 -// BOUNDING_BOX-es per image are allowed (one BOUNDING_BOX is defined -// per line). If an image has not yet been labeled, then it should be -// mentioned just once with no LABEL and the ",,,,,,," in place of the -// BOUNDING_BOX. For images which are known to not contain any -// bounding boxes, they should be labelled explictly as -// "NEGATIVE_IMAGE", followed by ",,,,,,," in place of the -// BOUNDING_BOX. -// Sample rows: -// TRAIN,gs://folder/image1.png,car,0.1,0.1,,,0.3,0.3,, -// TRAIN,gs://folder/image1.png,bike,.7,.6,,,.8,.9,, -// UNASSIGNED,gs://folder/im2.png,car,0.1,0.1,0.2,0.1,0.2,0.3,0.1,0.3 -// TEST,gs://folder/im3.png,,,,,,,,, -// TRAIN,gs://folder/im4.png,NEGATIVE_IMAGE,,,,,,,,, -// -// * For Video Classification: -// CSV file(s) with each line in format: -// ML_USE,GCS_FILE_PATH -// where ML_USE VALIDATE value should not be used. The GCS_FILE_PATH -// should lead to another .csv file which describes examples that have -// given ML_USE, using the following row format: -// GCS_FILE_PATH,(LABEL,TIME_SEGMENT_START,TIME_SEGMENT_END | ,,) -// Here GCS_FILE_PATH leads to a video of up to 50GB in size and up -// to 3h duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. -// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the -// length of the video, and end has to be after the start. Any segment -// of a video which has one or more labels on it, is considered a -// hard negative for all other labels. Any segment with no labels on -// it is considered to be unknown. If a whole video is unknown, then -// it shuold be mentioned just once with ",," in place of LABEL, -// TIME_SEGMENT_START,TIME_SEGMENT_END. -// Sample top level CSV file: -// TRAIN,gs://folder/train_videos.csv -// TEST,gs://folder/test_videos.csv -// UNASSIGNED,gs://folder/other_videos.csv -// Sample rows of a CSV file for a particular ML_USE: -// gs://folder/video1.avi,car,120,180.000021 -// gs://folder/video1.avi,bike,150,180.000021 -// gs://folder/vid2.avi,car,0,60.5 -// gs://folder/vid3.avi,,, -// -// * For Video Object Tracking: -// CSV file(s) with each line in format: -// ML_USE,GCS_FILE_PATH -// where ML_USE VALIDATE value should not be used. The GCS_FILE_PATH -// should lead to another .csv file which describes examples that have -// given ML_USE, using one of the following row format: -// GCS_FILE_PATH,LABEL,[INSTANCE_ID],TIMESTAMP,BOUNDING_BOX -// or -// GCS_FILE_PATH,,,,,,,,,, -// Here GCS_FILE_PATH leads to a video of up to 50GB in size and up -// to 3h duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. -// Providing INSTANCE_IDs can help to obtain a better model. When -// a specific labeled entity leaves the video frame, and shows up -// afterwards it is not required, albeit preferable, that the same -// INSTANCE_ID is given to it. -// TIMESTAMP must be within the length of the video, the -// BOUNDING_BOX is assumed to be drawn on the closest video's frame -// to the TIMESTAMP. Any mentioned by the TIMESTAMP frame is expected -// to be exhaustively labeled and no more than 500 BOUNDING_BOX-es per -// frame are allowed. If a whole video is unknown, then it should be -// mentioned just once with ",,,,,,,,,," in place of LABEL, -// [INSTANCE_ID],TIMESTAMP,BOUNDING_BOX. -// Sample top level CSV file: -// TRAIN,gs://folder/train_videos.csv -// TEST,gs://folder/test_videos.csv -// UNASSIGNED,gs://folder/other_videos.csv -// Seven sample rows of a CSV file for a particular ML_USE: -// gs://folder/video1.avi,car,1,12.10,0.8,0.8,0.9,0.8,0.9,0.9,0.8,0.9 -// gs://folder/video1.avi,car,1,12.90,0.4,0.8,0.5,0.8,0.5,0.9,0.4,0.9 -// gs://folder/video1.avi,car,2,12.10,.4,.2,.5,.2,.5,.3,.4,.3 -// gs://folder/video1.avi,car,2,12.90,.8,.2,,,.9,.3,, -// gs://folder/video1.avi,bike,,12.50,.45,.45,,,.55,.55,, -// gs://folder/video2.avi,car,1,0,.1,.9,,,.9,.1,, -// gs://folder/video2.avi,,,,,,,,,,, -// * For Text Extraction: -// CSV file(s) with each line in format: -// ML_USE,GCS_FILE_PATH -// GCS_FILE_PATH leads to a .JSONL (that is, JSON Lines) file which -// either imports text in-line or as documents. Any given -// .JSONL file must be 100MB or smaller. -// The in-line .JSONL file contains, per line, a proto that wraps a -// TextSnippet proto (in json representation) followed by one or more -// AnnotationPayload protos (called annotations), which have -// display_name and text_extraction detail populated. The given text -// is expected to be annotated exhaustively, for example, if you look -// for animals and text contains "dolphin" that is not labeled, then -// "dolphin" is assumed to not be an animal. Any given text snippet -// content must be 10KB or smaller, and also be UTF-8 NFC encoded -// (ASCII already is). -// The document .JSONL file contains, per line, a proto that wraps a -// Document proto. The Document proto must have either document_text -// or input_config set. In document_text case, the Document proto may -// also contain the spatial information of the document, including -// layout, document dimension and page number. In input_config case, -// only PDF documents are supported now, and each document may be up -// to 2MB large. Currently, annotations on documents cannot be -// specified at import. -// Three sample CSV rows: -// TRAIN,gs://folder/file1.jsonl -// VALIDATE,gs://folder/file2.jsonl -// TEST,gs://folder/file3.jsonl -// Sample in-line JSON Lines file for entity extraction (presented here -// with artificial line breaks, but the only actual line break is -// denoted by \n).: -// { -// "document": { -// "document_text": {"content": "dog cat"} -// "layout": [ -// { -// "text_segment": { -// "start_offset": 0, -// "end_offset": 3, -// }, -// "page_number": 1, -// "bounding_poly": { -// "normalized_vertices": [ -// {"x": 0.1, "y": 0.1}, -// {"x": 0.1, "y": 0.3}, -// {"x": 0.3, "y": 0.3}, -// {"x": 0.3, "y": 0.1}, -// ], -// }, -// "text_segment_type": TOKEN, -// }, -// { -// "text_segment": { -// "start_offset": 4, -// "end_offset": 7, -// }, -// "page_number": 1, -// "bounding_poly": { -// "normalized_vertices": [ -// {"x": 0.4, "y": 0.1}, -// {"x": 0.4, "y": 0.3}, -// {"x": 0.8, "y": 0.3}, -// {"x": 0.8, "y": 0.1}, -// ], -// }, -// "text_segment_type": TOKEN, -// } -// -// ], -// "document_dimensions": { -// "width": 8.27, -// "height": 11.69, -// "unit": INCH, -// } -// "page_count": 1, -// }, -// "annotations": [ -// { -// "display_name": "animal", -// "text_extraction": {"text_segment": {"start_offset": 0, -// "end_offset": 3}} -// }, -// { -// "display_name": "animal", -// "text_extraction": {"text_segment": {"start_offset": 4, -// "end_offset": 7}} -// } -// ], -// }\n -// { -// "text_snippet": { -// "content": "This dog is good." -// }, -// "annotations": [ -// { -// "display_name": "animal", -// "text_extraction": { -// "text_segment": {"start_offset": 5, "end_offset": 8} -// } -// } -// ] -// } -// Sample document JSON Lines file (presented here with artificial line -// breaks, but the only actual line break is denoted by \n).: -// { -// "document": { -// "input_config": { -// "gcs_source": { "input_uris": [ "gs://folder/document1.pdf" ] -// } -// } -// } -// }\n -// { -// "document": { -// "input_config": { -// "gcs_source": { "input_uris": [ "gs://folder/document2.pdf" ] -// } -// } -// } -// } -// -// * For Text Classification: -// CSV file(s) with each line in format: -// ML_USE,(TEXT_SNIPPET | GCS_FILE_PATH),LABEL,LABEL,... -// TEXT_SNIPPET and GCS_FILE_PATH are distinguished by a pattern. If -// the column content is a valid gcs file path, i.e. prefixed by -// "gs://", it will be treated as a GCS_FILE_PATH, else if the content -// is enclosed within double quotes (""), it is -// treated as a TEXT_SNIPPET. In the GCS_FILE_PATH case, the path -// must lead to a .txt file with UTF-8 encoding, for example, -// "gs://folder/content.txt", and the content in it is extracted -// as a text snippet. In TEXT_SNIPPET case, the column content -// excluding quotes is treated as to be imported text snippet. In -// both cases, the text snippet/file size must be within 128kB. -// Maximum 100 unique labels are allowed per CSV row. -// Sample rows: -// TRAIN,"They have bad food and very rude",RudeService,BadFood -// TRAIN,gs://folder/content.txt,SlowService -// TEST,"Typically always bad service there.",RudeService -// VALIDATE,"Stomach ache to go.",BadFood -// -// * For Text Sentiment: -// CSV file(s) with each line in format: -// ML_USE,(TEXT_SNIPPET | GCS_FILE_PATH),SENTIMENT -// TEXT_SNIPPET and GCS_FILE_PATH are distinguished by a pattern. If -// the column content is a valid gcs file path, that is, prefixed by -// "gs://", it is treated as a GCS_FILE_PATH, otherwise it is treated -// as a TEXT_SNIPPET. In the GCS_FILE_PATH case, the path -// must lead to a .txt file with UTF-8 encoding, for example, -// "gs://folder/content.txt", and the content in it is extracted -// as a text snippet. In TEXT_SNIPPET case, the column content itself -// is treated as to be imported text snippet. In both cases, the -// text snippet must be up to 500 characters long. -// Sample rows: -// TRAIN,"@freewrytin this is way too good for your product",2 -// TRAIN,"I need this product so bad",3 -// TEST,"Thank you for this product.",4 -// VALIDATE,gs://folder/content.txt,2 -// -// * For Tables: -// Either -// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] or -// -// [bigquery_source][google.cloud.automl.v1beta1.InputConfig.bigquery_source] -// can be used. All inputs is concatenated into a single -// -// [primary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_name] -// For gcs_source: -// CSV file(s), where the first row of the first file is the header, -// containing unique column names. If the first row of a subsequent -// file is the same as the header, then it is also treated as a -// header. All other rows contain values for the corresponding -// columns. -// Each .CSV file by itself must be 10GB or smaller, and their total -// size must be 100GB or smaller. -// First three sample rows of a CSV file: -// "Id","First Name","Last Name","Dob","Addresses" -// -// "1","John","Doe","1968-01-22","[{"status":"current","address":"123_First_Avenue","city":"Seattle","state":"WA","zip":"11111","numberOfYears":"1"},{"status":"previous","address":"456_Main_Street","city":"Portland","state":"OR","zip":"22222","numberOfYears":"5"}]" -// -// "2","Jane","Doe","1980-10-16","[{"status":"current","address":"789_Any_Avenue","city":"Albany","state":"NY","zip":"33333","numberOfYears":"2"},{"status":"previous","address":"321_Main_Street","city":"Hoboken","state":"NJ","zip":"44444","numberOfYears":"3"}]} -// For bigquery_source: -// An URI of a BigQuery table. The user data size of the BigQuery -// table must be 100GB or smaller. -// An imported table must have between 2 and 1,000 columns, inclusive, -// and between 1000 and 100,000,000 rows, inclusive. There are at most 5 -// import data running in parallel. -// Definitions: -// ML_USE = "TRAIN" | "VALIDATE" | "TEST" | "UNASSIGNED" -// Describes how the given example (file) should be used for model -// training. "UNASSIGNED" can be used when user has no preference. -// GCS_FILE_PATH = A path to file on GCS, e.g. "gs://folder/image1.png". -// LABEL = A display name of an object on an image, video etc., e.g. "dog". -// Must be up to 32 characters long and can consist only of ASCII -// Latin letters A-Z and a-z, underscores(_), and ASCII digits 0-9. -// For each label an AnnotationSpec is created which display_name -// becomes the label; AnnotationSpecs are given back in predictions. -// INSTANCE_ID = A positive integer that identifies a specific instance of a -// labeled entity on an example. Used e.g. to track two cars on -// a video while being able to tell apart which one is which. -// BOUNDING_BOX = VERTEX,VERTEX,VERTEX,VERTEX | VERTEX,,,VERTEX,, -// A rectangle parallel to the frame of the example (image, -// video). If 4 vertices are given they are connected by edges -// in the order provided, if 2 are given they are recognized -// as diagonally opposite vertices of the rectangle. -// VERTEX = COORDINATE,COORDINATE -// First coordinate is horizontal (x), the second is vertical (y). -// COORDINATE = A float in 0 to 1 range, relative to total length of -// image or video in given dimension. For fractions the -// leading non-decimal 0 can be omitted (i.e. 0.3 = .3). -// Point 0,0 is in top left. -// TIME_SEGMENT_START = TIME_OFFSET -// Expresses a beginning, inclusive, of a time segment -// within an example that has a time dimension -// (e.g. video). -// TIME_SEGMENT_END = TIME_OFFSET -// Expresses an end, exclusive, of a time segment within -// an example that has a time dimension (e.g. video). -// TIME_OFFSET = A number of seconds as measured from the start of an -// example (e.g. video). Fractions are allowed, up to a -// microsecond precision. "inf" is allowed, and it means the end -// of the example. -// TEXT_SNIPPET = A content of a text snippet, UTF-8 encoded, enclosed within -// double quotes (""). -// SENTIMENT = An integer between 0 and -// Dataset.text_sentiment_dataset_metadata.sentiment_max -// (inclusive). Describes the ordinal of the sentiment - higher -// value means a more positive sentiment. All the values are -// completely relative, i.e. neither 0 needs to mean a negative or -// neutral sentiment nor sentiment_max needs to mean a positive one -// - it is just required that 0 is the least positive sentiment -// in the data, and sentiment_max is the most positive one. -// The SENTIMENT shouldn't be confused with "score" or "magnitude" -// from the previous Natural Language Sentiment Analysis API. -// All SENTIMENT values between 0 and sentiment_max must be -// represented in the imported data. On prediction the same 0 to -// sentiment_max range will be used. The difference between -// neighboring sentiment values needs not to be uniform, e.g. 1 and -// 2 may be similar whereas the difference between 2 and 3 may be -// huge. -// -// Errors: -// If any of the provided CSV files can't be parsed or if more than certain -// percent of CSV rows cannot be processed then the operation fails and -// nothing is imported. Regardless of overall success or failure the per-row -// failures, up to a certain count cap, is listed in -// Operation.metadata.partial_failures. -// -message InputConfig { - // The source of the input. - oneof source { - // The Google Cloud Storage location for the input content. - // In ImportData, the gcs_source points to a csv with structure described in - // the comment. - GcsSource gcs_source = 1; - - // The BigQuery location for the input content. - BigQuerySource bigquery_source = 3; - } - - // Additional domain-specific parameters describing the semantic of the - // imported data, any string must be up to 25000 - // characters long. - // - // * For Tables: - // `schema_inference_version` - (integer) Required. The version of the - // algorithm that should be used for the initial inference of the - // schema (columns' DataTypes) of the table the data is being imported - // into. Allowed values: "1". - map params = 2; -} - -// Input configuration for BatchPredict Action. -// -// The format of input depends on the ML problem of the model used for -// prediction. As input source the -// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] -// is expected, unless specified otherwise. -// -// The formats are represented in EBNF with commas being literal and with -// non-terminal symbols defined near the end of this comment. The formats -// are: -// -// * For Image Classification: -// CSV file(s) with each line having just a single column: -// GCS_FILE_PATH -// which leads to image of up to 30MB in size. Supported -// extensions: .JPEG, .GIF, .PNG. This path is treated as the ID in -// the Batch predict output. -// Three sample rows: -// gs://folder/image1.jpeg -// gs://folder/image2.gif -// gs://folder/image3.png -// -// * For Image Object Detection: -// CSV file(s) with each line having just a single column: -// GCS_FILE_PATH -// which leads to image of up to 30MB in size. Supported -// extensions: .JPEG, .GIF, .PNG. This path is treated as the ID in -// the Batch predict output. -// Three sample rows: -// gs://folder/image1.jpeg -// gs://folder/image2.gif -// gs://folder/image3.png -// * For Video Classification: -// CSV file(s) with each line in format: -// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END -// GCS_FILE_PATH leads to video of up to 50GB in size and up to 3h -// duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. -// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the -// length of the video, and end has to be after the start. -// Three sample rows: -// gs://folder/video1.mp4,10,40 -// gs://folder/video1.mp4,20,60 -// gs://folder/vid2.mov,0,inf -// -// * For Video Object Tracking: -// CSV file(s) with each line in format: -// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END -// GCS_FILE_PATH leads to video of up to 50GB in size and up to 3h -// duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. -// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the -// length of the video, and end has to be after the start. -// Three sample rows: -// gs://folder/video1.mp4,10,240 -// gs://folder/video1.mp4,300,360 -// gs://folder/vid2.mov,0,inf -// * For Text Classification: -// CSV file(s) with each line having just a single column: -// GCS_FILE_PATH | TEXT_SNIPPET -// Any given text file can have size upto 128kB. -// Any given text snippet content must have 60,000 characters or less. -// Three sample rows: -// gs://folder/text1.txt -// "Some text content to predict" -// gs://folder/text3.pdf -// Supported file extensions: .txt, .pdf -// -// * For Text Sentiment: -// CSV file(s) with each line having just a single column: -// GCS_FILE_PATH | TEXT_SNIPPET -// Any given text file can have size upto 128kB. -// Any given text snippet content must have 500 characters or less. -// Three sample rows: -// gs://folder/text1.txt -// "Some text content to predict" -// gs://folder/text3.pdf -// Supported file extensions: .txt, .pdf -// -// * For Text Extraction -// .JSONL (i.e. JSON Lines) file(s) which either provide text in-line or -// as documents (for a single BatchPredict call only one of the these -// formats may be used). -// The in-line .JSONL file(s) contain per line a proto that -// wraps a temporary user-assigned TextSnippet ID (string up to 2000 -// characters long) called "id", a TextSnippet proto (in -// json representation) and zero or more TextFeature protos. Any given -// text snippet content must have 30,000 characters or less, and also -// be UTF-8 NFC encoded (ASCII already is). The IDs provided should be -// unique. -// The document .JSONL file(s) contain, per line, a proto that wraps a -// Document proto with input_config set. Only PDF documents are -// supported now, and each document must be up to 2MB large. -// Any given .JSONL file must be 100MB or smaller, and no more than 20 -// files may be given. -// Sample in-line JSON Lines file (presented here with artificial line -// breaks, but the only actual line break is denoted by \n): -// { -// "id": "my_first_id", -// "text_snippet": { "content": "dog car cat"}, -// "text_features": [ -// { -// "text_segment": {"start_offset": 4, "end_offset": 6}, -// "structural_type": PARAGRAPH, -// "bounding_poly": { -// "normalized_vertices": [ -// {"x": 0.1, "y": 0.1}, -// {"x": 0.1, "y": 0.3}, -// {"x": 0.3, "y": 0.3}, -// {"x": 0.3, "y": 0.1}, -// ] -// }, -// } -// ], -// }\n -// { -// "id": "2", -// "text_snippet": { -// "content": "An elaborate content", -// "mime_type": "text/plain" -// } -// } -// Sample document JSON Lines file (presented here with artificial line -// breaks, but the only actual line break is denoted by \n).: -// { -// "document": { -// "input_config": { -// "gcs_source": { "input_uris": [ "gs://folder/document1.pdf" ] -// } -// } -// } -// }\n -// { -// "document": { -// "input_config": { -// "gcs_source": { "input_uris": [ "gs://folder/document2.pdf" ] -// } -// } -// } -// } -// -// * For Tables: -// Either -// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] or -// -// [bigquery_source][google.cloud.automl.v1beta1.InputConfig.bigquery_source]. -// GCS case: -// CSV file(s), each by itself 10GB or smaller and total size must be -// 100GB or smaller, where first file must have a header containing -// column names. If the first row of a subsequent file is the same as -// the header, then it is also treated as a header. All other rows -// contain values for the corresponding columns. -// The column names must contain the model's -// -// [input_feature_column_specs'][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] -// -// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] -// (order doesn't matter). The columns corresponding to the model's -// input feature column specs must contain values compatible with the -// column spec's data types. Prediction on all the rows, i.e. the CSV -// lines, will be attempted. For FORECASTING -// -// [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: -// all columns having -// -// [TIME_SERIES_AVAILABLE_PAST_ONLY][google.cloud.automl.v1beta1.ColumnSpec.ForecastingMetadata.ColumnType] -// type will be ignored. -// First three sample rows of a CSV file: -// "First Name","Last Name","Dob","Addresses" -// -// "John","Doe","1968-01-22","[{"status":"current","address":"123_First_Avenue","city":"Seattle","state":"WA","zip":"11111","numberOfYears":"1"},{"status":"previous","address":"456_Main_Street","city":"Portland","state":"OR","zip":"22222","numberOfYears":"5"}]" -// -// "Jane","Doe","1980-10-16","[{"status":"current","address":"789_Any_Avenue","city":"Albany","state":"NY","zip":"33333","numberOfYears":"2"},{"status":"previous","address":"321_Main_Street","city":"Hoboken","state":"NJ","zip":"44444","numberOfYears":"3"}]} -// BigQuery case: -// An URI of a BigQuery table. The user data size of the BigQuery -// table must be 100GB or smaller. -// The column names must contain the model's -// -// [input_feature_column_specs'][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] -// -// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] -// (order doesn't matter). The columns corresponding to the model's -// input feature column specs must contain values compatible with the -// column spec's data types. Prediction on all the rows of the table -// will be attempted. For FORECASTING -// -// [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: -// all columns having -// -// [TIME_SERIES_AVAILABLE_PAST_ONLY][google.cloud.automl.v1beta1.ColumnSpec.ForecastingMetadata.ColumnType] -// type will be ignored. -// -// Definitions: -// GCS_FILE_PATH = A path to file on GCS, e.g. "gs://folder/video.avi". -// TEXT_SNIPPET = A content of a text snippet, UTF-8 encoded, enclosed within -// double quotes ("") -// TIME_SEGMENT_START = TIME_OFFSET -// Expresses a beginning, inclusive, of a time segment -// within an -// example that has a time dimension (e.g. video). -// TIME_SEGMENT_END = TIME_OFFSET -// Expresses an end, exclusive, of a time segment within -// an example that has a time dimension (e.g. video). -// TIME_OFFSET = A number of seconds as measured from the start of an -// example (e.g. video). Fractions are allowed, up to a -// microsecond precision. "inf" is allowed and it means the end -// of the example. -// -// Errors: -// If any of the provided CSV files can't be parsed or if more than certain -// percent of CSV rows cannot be processed then the operation fails and -// prediction does not happen. Regardless of overall success or failure the -// per-row failures, up to a certain count cap, will be listed in -// Operation.metadata.partial_failures. -message BatchPredictInputConfig { - // Required. The source of the input. - oneof source { - // The Google Cloud Storage location for the input content. - GcsSource gcs_source = 1; - - // The BigQuery location for the input content. - BigQuerySource bigquery_source = 2; - } -} - -// Input configuration of a [Document][google.cloud.automl.v1beta1.Document]. -message DocumentInputConfig { - // The Google Cloud Storage location of the document file. Only a single path - // should be given. - // Max supported size: 512MB. - // Supported extensions: .PDF. - GcsSource gcs_source = 1; -} - -// * For Translation: -// CSV file `translation.csv`, with each line in format: -// ML_USE,GCS_FILE_PATH -// GCS_FILE_PATH leads to a .TSV file which describes examples that have -// given ML_USE, using the following row format per line: -// TEXT_SNIPPET (in source language) \t TEXT_SNIPPET (in target -// language) -// -// * For Tables: -// Output depends on whether the dataset was imported from GCS or -// BigQuery. -// GCS case: -// -// [gcs_destination][google.cloud.automl.v1beta1.OutputConfig.gcs_destination] -// must be set. Exported are CSV file(s) `tables_1.csv`, -// `tables_2.csv`,...,`tables_N.csv` with each having as header line -// the table's column names, and all other lines contain values for -// the header columns. -// BigQuery case: -// -// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] -// pointing to a BigQuery project must be set. In the given project a -// new dataset will be created with name -// -// `export_data__` -// where will be made -// BigQuery-dataset-name compatible (e.g. most special characters will -// become underscores), and timestamp will be in -// YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" format. In that -// dataset a new table called `primary_table` will be created, and -// filled with precisely the same data as this obtained on import. -message OutputConfig { - // Required. The destination of the output. - oneof destination { - // The Google Cloud Storage location where the output is to be written to. - // For Image Object Detection, Text Extraction, Video Classification and - // Tables, in the given directory a new directory will be created with name: - // export_data-- where - // timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format. All export - // output will be written into that directory. - GcsDestination gcs_destination = 1; - - // The BigQuery location where the output is to be written to. - BigQueryDestination bigquery_destination = 2; - } -} - -// Output configuration for BatchPredict Action. -// -// As destination the -// -// [gcs_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.gcs_destination] -// must be set unless specified otherwise for a domain. If gcs_destination is -// set then in the given directory a new directory is created. Its name -// will be -// "prediction--", -// where timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format. The contents -// of it depends on the ML problem the predictions are made for. -// -// * For Image Classification: -// In the created directory files `image_classification_1.jsonl`, -// `image_classification_2.jsonl`,...,`image_classification_N.jsonl` -// will be created, where N may be 1, and depends on the -// total number of the successfully predicted images and annotations. -// A single image will be listed only once with all its annotations, -// and its annotations will never be split across files. -// Each .JSONL file will contain, per line, a JSON representation of a -// proto that wraps image's "ID" : "" followed by a list of -// zero or more AnnotationPayload protos (called annotations), which -// have classification detail populated. -// If prediction for any image failed (partially or completely), then an -// additional `errors_1.jsonl`, `errors_2.jsonl`,..., `errors_N.jsonl` -// files will be created (N depends on total number of failed -// predictions). These files will have a JSON representation of a proto -// that wraps the same "ID" : "" but here followed by -// exactly one -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// containing only `code` and `message`fields. -// -// * For Image Object Detection: -// In the created directory files `image_object_detection_1.jsonl`, -// `image_object_detection_2.jsonl`,...,`image_object_detection_N.jsonl` -// will be created, where N may be 1, and depends on the -// total number of the successfully predicted images and annotations. -// Each .JSONL file will contain, per line, a JSON representation of a -// proto that wraps image's "ID" : "" followed by a list of -// zero or more AnnotationPayload protos (called annotations), which -// have image_object_detection detail populated. A single image will -// be listed only once with all its annotations, and its annotations -// will never be split across files. -// If prediction for any image failed (partially or completely), then -// additional `errors_1.jsonl`, `errors_2.jsonl`,..., `errors_N.jsonl` -// files will be created (N depends on total number of failed -// predictions). These files will have a JSON representation of a proto -// that wraps the same "ID" : "" but here followed by -// exactly one -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// containing only `code` and `message`fields. -// * For Video Classification: -// In the created directory a video_classification.csv file, and a .JSON -// file per each video classification requested in the input (i.e. each -// line in given CSV(s)), will be created. -// -// The format of video_classification.csv is: -// -// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END,JSON_FILE_NAME,STATUS -// where: -// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END = matches 1 to 1 -// the prediction input lines (i.e. video_classification.csv has -// precisely the same number of lines as the prediction input had.) -// JSON_FILE_NAME = Name of .JSON file in the output directory, which -// contains prediction responses for the video time segment. -// STATUS = "OK" if prediction completed successfully, or an error code -// with message otherwise. If STATUS is not "OK" then the .JSON file -// for that line may not exist or be empty. -// -// Each .JSON file, assuming STATUS is "OK", will contain a list of -// AnnotationPayload protos in JSON format, which are the predictions -// for the video time segment the file is assigned to in the -// video_classification.csv. All AnnotationPayload protos will have -// video_classification field set, and will be sorted by -// video_classification.type field (note that the returned types are -// governed by `classifaction_types` parameter in -// [PredictService.BatchPredictRequest.params][]). -// -// * For Video Object Tracking: -// In the created directory a video_object_tracking.csv file will be -// created, and multiple files video_object_trackinng_1.json, -// video_object_trackinng_2.json,..., video_object_trackinng_N.json, -// where N is the number of requests in the input (i.e. the number of -// lines in given CSV(s)). -// -// The format of video_object_tracking.csv is: -// -// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END,JSON_FILE_NAME,STATUS -// where: -// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END = matches 1 to 1 -// the prediction input lines (i.e. video_object_tracking.csv has -// precisely the same number of lines as the prediction input had.) -// JSON_FILE_NAME = Name of .JSON file in the output directory, which -// contains prediction responses for the video time segment. -// STATUS = "OK" if prediction completed successfully, or an error -// code with message otherwise. If STATUS is not "OK" then the .JSON -// file for that line may not exist or be empty. -// -// Each .JSON file, assuming STATUS is "OK", will contain a list of -// AnnotationPayload protos in JSON format, which are the predictions -// for each frame of the video time segment the file is assigned to in -// video_object_tracking.csv. All AnnotationPayload protos will have -// video_object_tracking field set. -// * For Text Classification: -// In the created directory files `text_classification_1.jsonl`, -// `text_classification_2.jsonl`,...,`text_classification_N.jsonl` -// will be created, where N may be 1, and depends on the -// total number of inputs and annotations found. -// -// Each .JSONL file will contain, per line, a JSON representation of a -// proto that wraps input text snippet or input text file and a list of -// zero or more AnnotationPayload protos (called annotations), which -// have classification detail populated. A single text snippet or file -// will be listed only once with all its annotations, and its -// annotations will never be split across files. -// -// If prediction for any text snippet or file failed (partially or -// completely), then additional `errors_1.jsonl`, `errors_2.jsonl`,..., -// `errors_N.jsonl` files will be created (N depends on total number of -// failed predictions). These files will have a JSON representation of a -// proto that wraps input text snippet or input text file followed by -// exactly one -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// containing only `code` and `message`. -// -// * For Text Sentiment: -// In the created directory files `text_sentiment_1.jsonl`, -// `text_sentiment_2.jsonl`,...,`text_sentiment_N.jsonl` -// will be created, where N may be 1, and depends on the -// total number of inputs and annotations found. -// -// Each .JSONL file will contain, per line, a JSON representation of a -// proto that wraps input text snippet or input text file and a list of -// zero or more AnnotationPayload protos (called annotations), which -// have text_sentiment detail populated. A single text snippet or file -// will be listed only once with all its annotations, and its -// annotations will never be split across files. -// -// If prediction for any text snippet or file failed (partially or -// completely), then additional `errors_1.jsonl`, `errors_2.jsonl`,..., -// `errors_N.jsonl` files will be created (N depends on total number of -// failed predictions). These files will have a JSON representation of a -// proto that wraps input text snippet or input text file followed by -// exactly one -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// containing only `code` and `message`. -// -// * For Text Extraction: -// In the created directory files `text_extraction_1.jsonl`, -// `text_extraction_2.jsonl`,...,`text_extraction_N.jsonl` -// will be created, where N may be 1, and depends on the -// total number of inputs and annotations found. -// The contents of these .JSONL file(s) depend on whether the input -// used inline text, or documents. -// If input was inline, then each .JSONL file will contain, per line, -// a JSON representation of a proto that wraps given in request text -// snippet's "id" (if specified), followed by input text snippet, -// and a list of zero or more -// AnnotationPayload protos (called annotations), which have -// text_extraction detail populated. A single text snippet will be -// listed only once with all its annotations, and its annotations will -// never be split across files. -// If input used documents, then each .JSONL file will contain, per -// line, a JSON representation of a proto that wraps given in request -// document proto, followed by its OCR-ed representation in the form -// of a text snippet, finally followed by a list of zero or more -// AnnotationPayload protos (called annotations), which have -// text_extraction detail populated and refer, via their indices, to -// the OCR-ed text snippet. A single document (and its text snippet) -// will be listed only once with all its annotations, and its -// annotations will never be split across files. -// If prediction for any text snippet failed (partially or completely), -// then additional `errors_1.jsonl`, `errors_2.jsonl`,..., -// `errors_N.jsonl` files will be created (N depends on total number of -// failed predictions). These files will have a JSON representation of a -// proto that wraps either the "id" : "" (in case of inline) -// or the document proto (in case of document) but here followed by -// exactly one -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// containing only `code` and `message`. -// -// * For Tables: -// Output depends on whether -// -// [gcs_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.gcs_destination] -// or -// -// [bigquery_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.bigquery_destination] -// is set (either is allowed). -// GCS case: -// In the created directory files `tables_1.csv`, `tables_2.csv`,..., -// `tables_N.csv` will be created, where N may be 1, and depends on -// the total number of the successfully predicted rows. -// For all CLASSIFICATION -// -// [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: -// Each .csv file will contain a header, listing all columns' -// -// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] -// given on input followed by M target column names in the format of -// -// "<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] -// -// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>__score" where M is the number of distinct target values, -// i.e. number of distinct values in the target column of the table -// used to train the model. Subsequent lines will contain the -// respective values of successfully predicted rows, with the last, -// i.e. the target, columns having the corresponding prediction -// [scores][google.cloud.automl.v1beta1.TablesAnnotation.score]. -// For REGRESSION and FORECASTING -// -// [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: -// Each .csv file will contain a header, listing all columns' -// [display_name-s][google.cloud.automl.v1beta1.display_name] given -// on input followed by the predicted target column with name in the -// format of -// -// "predicted_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] -// -// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>" -// Subsequent lines will contain the respective values of -// successfully predicted rows, with the last, i.e. the target, -// column having the predicted target value. -// If prediction for any rows failed, then an additional -// `errors_1.csv`, `errors_2.csv`,..., `errors_N.csv` will be -// created (N depends on total number of failed rows). These files -// will have analogous format as `tables_*.csv`, but always with a -// single target column having -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// represented as a JSON string, and containing only `code` and -// `message`. -// BigQuery case: -// -// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] -// pointing to a BigQuery project must be set. In the given project a -// new dataset will be created with name -// `prediction__` -// where will be made -// BigQuery-dataset-name compatible (e.g. most special characters will -// become underscores), and timestamp will be in -// YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" format. In the dataset -// two tables will be created, `predictions`, and `errors`. -// The `predictions` table's column names will be the input columns' -// -// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] -// followed by the target column with name in the format of -// -// "predicted_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] -// -// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>" -// The input feature columns will contain the respective values of -// successfully predicted rows, with the target column having an -// ARRAY of -// -// [AnnotationPayloads][google.cloud.automl.v1beta1.AnnotationPayload], -// represented as STRUCT-s, containing -// [TablesAnnotation][google.cloud.automl.v1beta1.TablesAnnotation]. -// The `errors` table contains rows for which the prediction has -// failed, it has analogous input columns while the target column name -// is in the format of -// -// "errors_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] -// -// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>", -// and as a value has -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// represented as a STRUCT, and containing only `code` and `message`. -message BatchPredictOutputConfig { - // Required. The destination of the output. - oneof destination { - // The Google Cloud Storage location of the directory where the output is to - // be written to. - GcsDestination gcs_destination = 1; - - // The BigQuery location where the output is to be written to. - BigQueryDestination bigquery_destination = 2; - } -} - -// Output configuration for ModelExport Action. -message ModelExportOutputConfig { - // Required. The destination of the output. - oneof destination { - // The Google Cloud Storage location where the model is to be written to. - // This location may only be set for the following model formats: - // "tflite", "edgetpu_tflite", "tf_saved_model", "tf_js", "core_ml". - // - // Under the directory given as the destination a new one with name - // "model-export--", - // where timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format, - // will be created. Inside the model and any of its supporting files - // will be written. - GcsDestination gcs_destination = 1; - - // The GCR location where model image is to be pushed to. This location - // may only be set for the following model formats: - // "docker". - // - // The model image will be created under the given URI. - GcrDestination gcr_destination = 3; - } - - // The format in which the model must be exported. The available, and default, - // formats depend on the problem and model type (if given problem and type - // combination doesn't have a format listed, it means its models are not - // exportable): - // - // * For Image Classification mobile-low-latency-1, mobile-versatile-1, - // mobile-high-accuracy-1: - // "tflite" (default), "edgetpu_tflite", "tf_saved_model", "tf_js", - // "docker". - // - // * For Image Classification mobile-core-ml-low-latency-1, - // mobile-core-ml-versatile-1, mobile-core-ml-high-accuracy-1: - // "core_ml" (default). - // Formats description: - // - // * tflite - Used for Android mobile devices. - // * edgetpu_tflite - Used for [Edge TPU](https://cloud.google.com/edge-tpu/) - // devices. - // * tf_saved_model - A tensorflow model in SavedModel format. - // * tf_js - A [TensorFlow.js](https://www.tensorflow.org/js) model that can - // be used in the browser and in Node.js using JavaScript. - // * docker - Used for Docker containers. Use the params field to customize - // the container. The container is verified to work correctly on - // ubuntu 16.04 operating system. See more at - // [containers - // - // quickstart](https: - // //cloud.google.com/vision/automl/docs/containers-gcs-quickstart) - // * core_ml - Used for iOS mobile devices. - string model_format = 4; - - // Additional model-type and format specific parameters describing the - // requirements for the to be exported model files, any string must be up to - // 25000 characters long. - // - // * For `docker` format: - // `cpu_architecture` - (string) "x86_64" (default). - // `gpu_architecture` - (string) "none" (default), "nvidia". - map params = 2; -} - -// Output configuration for ExportEvaluatedExamples Action. Note that this call -// is available only for 30 days since the moment the model was evaluated. -// The output depends on the domain, as follows (note that only examples from -// the TEST set are exported): -// -// * For Tables: -// -// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] -// pointing to a BigQuery project must be set. In the given project a -// new dataset will be created with name -// -// `export_evaluated_examples__` -// where will be made BigQuery-dataset-name -// compatible (e.g. most special characters will become underscores), -// and timestamp will be in YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" -// format. In the dataset an `evaluated_examples` table will be -// created. It will have all the same columns as the -// -// [primary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_spec_id] -// of the -// [dataset][google.cloud.automl.v1beta1.Model.dataset_id] from which -// the model was created, as they were at the moment of model's -// evaluation (this includes the target column with its ground -// truth), followed by a column called "predicted_". That -// last column will contain the model's prediction result for each -// respective row, given as ARRAY of -// [AnnotationPayloads][google.cloud.automl.v1beta1.AnnotationPayload], -// represented as STRUCT-s, containing -// [TablesAnnotation][google.cloud.automl.v1beta1.TablesAnnotation]. -message ExportEvaluatedExamplesOutputConfig { - // Required. The destination of the output. - oneof destination { - // The BigQuery location where the output is to be written to. - BigQueryDestination bigquery_destination = 2; - } -} - -// The Google Cloud Storage location for the input content. -message GcsSource { - // Required. Google Cloud Storage URIs to input files, up to 2000 characters - // long. Accepted forms: - // * Full object path, e.g. gs://bucket/directory/object.csv - repeated string input_uris = 1; -} - -// The BigQuery location for the input content. -message BigQuerySource { - // Required. BigQuery URI to a table, up to 2000 characters long. - // Accepted forms: - // * BigQuery path e.g. bq://projectId.bqDatasetId.bqTableId - string input_uri = 1; -} - -// The Google Cloud Storage location where the output is to be written to. -message GcsDestination { - // Required. Google Cloud Storage URI to output directory, up to 2000 - // characters long. - // Accepted forms: - // * Prefix path: gs://bucket/directory - // The requesting user must have write permission to the bucket. - // The directory is created if it doesn't exist. - string output_uri_prefix = 1; -} - -// The BigQuery location for the output content. -message BigQueryDestination { - // Required. BigQuery URI to a project, up to 2000 characters long. - // Accepted forms: - // * BigQuery path e.g. bq://projectId - string output_uri = 1; -} - -// The GCR location where the image must be pushed to. -message GcrDestination { - // Required. Google Contained Registry URI of the new image, up to 2000 - // characters long. See - // - // https: - // //cloud.google.com/container-registry/do - // // cs/pushing-and-pulling#pushing_an_image_to_a_registry - // Accepted forms: - // * [HOSTNAME]/[PROJECT-ID]/[IMAGE] - // * [HOSTNAME]/[PROJECT-ID]/[IMAGE]:[TAG] - // - // The requesting user must have permission to push images the project. - string output_uri = 1; -} diff --git a/google/cloud/automl_v1beta1/proto/model.proto b/google/cloud/automl_v1beta1/proto/model.proto deleted file mode 100644 index 2b2e8d73..00000000 --- a/google/cloud/automl_v1beta1/proto/model.proto +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/image.proto"; -import "google/cloud/automl/v1beta1/tables.proto"; -import "google/cloud/automl/v1beta1/text.proto"; -import "google/cloud/automl/v1beta1/translation.proto"; -import "google/cloud/automl/v1beta1/video.proto"; -import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// API proto representing a trained machine learning model. -message Model { - option (google.api.resource) = { - type: "automl.googleapis.com/Model" - pattern: "projects/{project}/locations/{location}/models/{model}" - }; - - // Deployment state of the model. - enum DeploymentState { - // Should not be used, an un-set enum has this value by default. - DEPLOYMENT_STATE_UNSPECIFIED = 0; - - // Model is deployed. - DEPLOYED = 1; - - // Model is not deployed. - UNDEPLOYED = 2; - } - - // Required. - // The model metadata that is specific to the problem type. - // Must match the metadata type of the dataset used to train the model. - oneof model_metadata { - // Metadata for translation models. - TranslationModelMetadata translation_model_metadata = 15; - - // Metadata for image classification models. - ImageClassificationModelMetadata image_classification_model_metadata = 13; - - // Metadata for text classification models. - TextClassificationModelMetadata text_classification_model_metadata = 14; - - // Metadata for image object detection models. - ImageObjectDetectionModelMetadata image_object_detection_model_metadata = 20; - - // Metadata for video classification models. - VideoClassificationModelMetadata video_classification_model_metadata = 23; - - // Metadata for video object tracking models. - VideoObjectTrackingModelMetadata video_object_tracking_model_metadata = 21; - - // Metadata for text extraction models. - TextExtractionModelMetadata text_extraction_model_metadata = 19; - - // Metadata for Tables models. - TablesModelMetadata tables_model_metadata = 24; - - // Metadata for text sentiment models. - TextSentimentModelMetadata text_sentiment_model_metadata = 22; - } - - // Output only. Resource name of the model. - // Format: `projects/{project_id}/locations/{location_id}/models/{model_id}` - string name = 1; - - // Required. The name of the model to show in the interface. The name can be - // up to 32 characters long and can consist only of ASCII Latin letters A-Z - // and a-z, underscores - // (_), and ASCII digits 0-9. It must start with a letter. - string display_name = 2; - - // Required. The resource ID of the dataset used to create the model. The dataset must - // come from the same ancestor project and location. - string dataset_id = 3; - - // Output only. Timestamp when the model training finished and can be used for prediction. - google.protobuf.Timestamp create_time = 7; - - // Output only. Timestamp when this model was last updated. - google.protobuf.Timestamp update_time = 11; - - // Output only. Deployment state of the model. A model can only serve - // prediction requests after it gets deployed. - DeploymentState deployment_state = 8; -} diff --git a/google/cloud/automl_v1beta1/proto/model_evaluation.proto b/google/cloud/automl_v1beta1/proto/model_evaluation.proto deleted file mode 100644 index d5633fcd..00000000 --- a/google/cloud/automl_v1beta1/proto/model_evaluation.proto +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/cloud/automl/v1beta1/detection.proto"; -import "google/cloud/automl/v1beta1/regression.proto"; -import "google/cloud/automl/v1beta1/tables.proto"; -import "google/cloud/automl/v1beta1/text_extraction.proto"; -import "google/cloud/automl/v1beta1/text_sentiment.proto"; -import "google/cloud/automl/v1beta1/translation.proto"; -import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Evaluation results of a model. -message ModelEvaluation { - option (google.api.resource) = { - type: "automl.googleapis.com/ModelEvaluation" - pattern: "projects/{project}/locations/{location}/models/{model}/modelEvaluations/{model_evaluation}" - }; - - // Output only. Problem type specific evaluation metrics. - oneof metrics { - // Model evaluation metrics for image, text, video and tables - // classification. - // Tables problem is considered a classification when the target column - // is CATEGORY DataType. - ClassificationEvaluationMetrics classification_evaluation_metrics = 8; - - // Model evaluation metrics for Tables regression. - // Tables problem is considered a regression when the target column - // has FLOAT64 DataType. - RegressionEvaluationMetrics regression_evaluation_metrics = 24; - - // Model evaluation metrics for translation. - TranslationEvaluationMetrics translation_evaluation_metrics = 9; - - // Model evaluation metrics for image object detection. - ImageObjectDetectionEvaluationMetrics image_object_detection_evaluation_metrics = 12; - - // Model evaluation metrics for video object tracking. - VideoObjectTrackingEvaluationMetrics video_object_tracking_evaluation_metrics = 14; - - // Evaluation metrics for text sentiment models. - TextSentimentEvaluationMetrics text_sentiment_evaluation_metrics = 11; - - // Evaluation metrics for text extraction models. - TextExtractionEvaluationMetrics text_extraction_evaluation_metrics = 13; - } - - // Output only. Resource name of the model evaluation. - // Format: - // - // `projects/{project_id}/locations/{location_id}/models/{model_id}/modelEvaluations/{model_evaluation_id}` - string name = 1; - - // Output only. The ID of the annotation spec that the model evaluation applies to. The - // The ID is empty for the overall model evaluation. - // For Tables annotation specs in the dataset do not exist and this ID is - // always not set, but for CLASSIFICATION - // - // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] - // the - // [display_name][google.cloud.automl.v1beta1.ModelEvaluation.display_name] - // field is used. - string annotation_spec_id = 2; - - // Output only. The value of - // [display_name][google.cloud.automl.v1beta1.AnnotationSpec.display_name] at - // the moment when the model was trained. Because this field returns a value - // at model training time, for different models trained from the same dataset, - // the values may differ, since display names could had been changed between - // the two model's trainings. - // For Tables CLASSIFICATION - // - // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] - // distinct values of the target column at the moment of the model evaluation - // are populated here. - // The display_name is empty for the overall model evaluation. - string display_name = 15; - - // Output only. Timestamp when this model evaluation was created. - google.protobuf.Timestamp create_time = 5; - - // Output only. The number of examples used for model evaluation, i.e. for - // which ground truth from time of model creation is compared against the - // predicted annotations created by the model. - // For overall ModelEvaluation (i.e. with annotation_spec_id not set) this is - // the total number of all examples used for evaluation. - // Otherwise, this is the count of examples that according to the ground - // truth were annotated by the - // - // [annotation_spec_id][google.cloud.automl.v1beta1.ModelEvaluation.annotation_spec_id]. - int32 evaluated_example_count = 6; -} diff --git a/google/cloud/automl_v1beta1/proto/operations.proto b/google/cloud/automl_v1beta1/proto/operations.proto deleted file mode 100644 index cce3fedc..00000000 --- a/google/cloud/automl_v1beta1/proto/operations.proto +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/io.proto"; -import "google/cloud/automl/v1beta1/model.proto"; -import "google/cloud/automl/v1beta1/model_evaluation.proto"; -import "google/protobuf/empty.proto"; -import "google/protobuf/timestamp.proto"; -import "google/rpc/status.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Metadata used across all long running operations returned by AutoML API. -message OperationMetadata { - // Ouptut only. Details of specific operation. Even if this field is empty, - // the presence allows to distinguish different types of operations. - oneof details { - // Details of a Delete operation. - DeleteOperationMetadata delete_details = 8; - - // Details of a DeployModel operation. - DeployModelOperationMetadata deploy_model_details = 24; - - // Details of an UndeployModel operation. - UndeployModelOperationMetadata undeploy_model_details = 25; - - // Details of CreateModel operation. - CreateModelOperationMetadata create_model_details = 10; - - // Details of ImportData operation. - ImportDataOperationMetadata import_data_details = 15; - - // Details of BatchPredict operation. - BatchPredictOperationMetadata batch_predict_details = 16; - - // Details of ExportData operation. - ExportDataOperationMetadata export_data_details = 21; - - // Details of ExportModel operation. - ExportModelOperationMetadata export_model_details = 22; - - // Details of ExportEvaluatedExamples operation. - ExportEvaluatedExamplesOperationMetadata export_evaluated_examples_details = 26; - } - - // Output only. Progress of operation. Range: [0, 100]. - // Not used currently. - int32 progress_percent = 13; - - // Output only. Partial failures encountered. - // E.g. single files that couldn't be read. - // This field should never exceed 20 entries. - // Status details field will contain standard GCP error details. - repeated google.rpc.Status partial_failures = 2; - - // Output only. Time when the operation was created. - google.protobuf.Timestamp create_time = 3; - - // Output only. Time when the operation was updated for the last time. - google.protobuf.Timestamp update_time = 4; -} - -// Details of operations that perform deletes of any entities. -message DeleteOperationMetadata { - -} - -// Details of DeployModel operation. -message DeployModelOperationMetadata { - -} - -// Details of UndeployModel operation. -message UndeployModelOperationMetadata { - -} - -// Details of CreateModel operation. -message CreateModelOperationMetadata { - -} - -// Details of ImportData operation. -message ImportDataOperationMetadata { - -} - -// Details of ExportData operation. -message ExportDataOperationMetadata { - // Further describes this export data's output. - // Supplements - // [OutputConfig][google.cloud.automl.v1beta1.OutputConfig]. - message ExportDataOutputInfo { - // The output location to which the exported data is written. - oneof output_location { - // The full path of the Google Cloud Storage directory created, into which - // the exported data is written. - string gcs_output_directory = 1; - - // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId - // format, into which the exported data is written. - string bigquery_output_dataset = 2; - } - } - - // Output only. Information further describing this export data's output. - ExportDataOutputInfo output_info = 1; -} - -// Details of BatchPredict operation. -message BatchPredictOperationMetadata { - // Further describes this batch predict's output. - // Supplements - // - // [BatchPredictOutputConfig][google.cloud.automl.v1beta1.BatchPredictOutputConfig]. - message BatchPredictOutputInfo { - // The output location into which prediction output is written. - oneof output_location { - // The full path of the Google Cloud Storage directory created, into which - // the prediction output is written. - string gcs_output_directory = 1; - - // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId - // format, into which the prediction output is written. - string bigquery_output_dataset = 2; - } - } - - // Output only. The input config that was given upon starting this - // batch predict operation. - BatchPredictInputConfig input_config = 1; - - // Output only. Information further describing this batch predict's output. - BatchPredictOutputInfo output_info = 2; -} - -// Details of ExportModel operation. -message ExportModelOperationMetadata { - // Further describes the output of model export. - // Supplements - // - // [ModelExportOutputConfig][google.cloud.automl.v1beta1.ModelExportOutputConfig]. - message ExportModelOutputInfo { - // The full path of the Google Cloud Storage directory created, into which - // the model will be exported. - string gcs_output_directory = 1; - } - - // Output only. Information further describing the output of this model - // export. - ExportModelOutputInfo output_info = 2; -} - -// Details of EvaluatedExamples operation. -message ExportEvaluatedExamplesOperationMetadata { - // Further describes the output of the evaluated examples export. - // Supplements - // - // [ExportEvaluatedExamplesOutputConfig][google.cloud.automl.v1beta1.ExportEvaluatedExamplesOutputConfig]. - message ExportEvaluatedExamplesOutputInfo { - // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId - // format, into which the output of export evaluated examples is written. - string bigquery_output_dataset = 2; - } - - // Output only. Information further describing the output of this evaluated - // examples export. - ExportEvaluatedExamplesOutputInfo output_info = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/prediction_service.proto b/google/cloud/automl_v1beta1/proto/prediction_service.proto deleted file mode 100644 index 0bcf685e..00000000 --- a/google/cloud/automl_v1beta1/proto/prediction_service.proto +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/annotation_payload.proto"; -import "google/cloud/automl/v1beta1/data_items.proto"; -import "google/cloud/automl/v1beta1/io.proto"; -import "google/cloud/automl/v1beta1/operations.proto"; -import "google/longrunning/operations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "PredictionServiceProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// AutoML Prediction API. -// -// On any input that is documented to expect a string parameter in -// snake_case or kebab-case, either of those cases is accepted. -service PredictionService { - option (google.api.default_host) = "automl.googleapis.com"; - option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; - - // Perform an online prediction. The prediction result will be directly - // returned in the response. - // Available for following ML problems, and their expected request payloads: - // * Image Classification - Image in .JPEG, .GIF or .PNG format, image_bytes - // up to 30MB. - // * Image Object Detection - Image in .JPEG, .GIF or .PNG format, image_bytes - // up to 30MB. - // * Text Classification - TextSnippet, content up to 60,000 characters, - // UTF-8 encoded. - // * Text Extraction - TextSnippet, content up to 30,000 characters, - // UTF-8 NFC encoded. - // * Translation - TextSnippet, content up to 25,000 characters, UTF-8 - // encoded. - // * Tables - Row, with column values matching the columns of the model, - // up to 5MB. Not available for FORECASTING - // - // [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]. - // * Text Sentiment - TextSnippet, content up 500 characters, UTF-8 - // encoded. - rpc Predict(PredictRequest) returns (PredictResponse) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/models/*}:predict" - body: "*" - }; - option (google.api.method_signature) = "name,payload,params"; - } - - // Perform a batch prediction. Unlike the online [Predict][google.cloud.automl.v1beta1.PredictionService.Predict], batch - // prediction result won't be immediately available in the response. Instead, - // a long running operation object is returned. User can poll the operation - // result via [GetOperation][google.longrunning.Operations.GetOperation] - // method. Once the operation is done, [BatchPredictResult][google.cloud.automl.v1beta1.BatchPredictResult] is returned in - // the [response][google.longrunning.Operation.response] field. - // Available for following ML problems: - // * Image Classification - // * Image Object Detection - // * Video Classification - // * Video Object Tracking * Text Extraction - // * Tables - rpc BatchPredict(BatchPredictRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/models/*}:batchPredict" - body: "*" - }; - option (google.api.method_signature) = "name,input_config,output_config,params"; - option (google.longrunning.operation_info) = { - response_type: "BatchPredictResult" - metadata_type: "OperationMetadata" - }; - } -} - -// Request message for [PredictionService.Predict][google.cloud.automl.v1beta1.PredictionService.Predict]. -message PredictRequest { - // Required. Name of the model requested to serve the prediction. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; - - // Required. Payload to perform a prediction on. The payload must match the - // problem type that the model was trained to solve. - ExamplePayload payload = 2 [(google.api.field_behavior) = REQUIRED]; - - // Additional domain-specific parameters, any string must be up to 25000 - // characters long. - // - // * For Image Classification: - // - // `score_threshold` - (float) A value from 0.0 to 1.0. When the model - // makes predictions for an image, it will only produce results that have - // at least this confidence score. The default is 0.5. - // - // * For Image Object Detection: - // `score_threshold` - (float) When Model detects objects on the image, - // it will only produce bounding boxes which have at least this - // confidence score. Value in 0 to 1 range, default is 0.5. - // `max_bounding_box_count` - (int64) No more than this number of bounding - // boxes will be returned in the response. Default is 100, the - // requested value may be limited by server. - // * For Tables: - // feature_importance - (boolean) Whether feature importance - // should be populated in the returned TablesAnnotation. - // The default is false. - map params = 3; -} - -// Response message for [PredictionService.Predict][google.cloud.automl.v1beta1.PredictionService.Predict]. -message PredictResponse { - // Prediction result. - // Translation and Text Sentiment will return precisely one payload. - repeated AnnotationPayload payload = 1; - - // The preprocessed example that AutoML actually makes prediction on. - // Empty if AutoML does not preprocess the input example. - // * For Text Extraction: - // If the input is a .pdf file, the OCR'ed text will be provided in - // [document_text][google.cloud.automl.v1beta1.Document.document_text]. - ExamplePayload preprocessed_input = 3; - - // Additional domain-specific prediction response metadata. - // - // * For Image Object Detection: - // `max_bounding_box_count` - (int64) At most that many bounding boxes per - // image could have been returned. - // - // * For Text Sentiment: - // `sentiment_score` - (float, deprecated) A value between -1 and 1, - // -1 maps to least positive sentiment, while 1 maps to the most positive - // one and the higher the score, the more positive the sentiment in the - // document is. Yet these values are relative to the training data, so - // e.g. if all data was positive then -1 will be also positive (though - // the least). - // The sentiment_score shouldn't be confused with "score" or "magnitude" - // from the previous Natural Language Sentiment Analysis API. - map metadata = 2; -} - -// Request message for [PredictionService.BatchPredict][google.cloud.automl.v1beta1.PredictionService.BatchPredict]. -message BatchPredictRequest { - // Required. Name of the model requested to serve the batch prediction. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; - - // Required. The input configuration for batch prediction. - BatchPredictInputConfig input_config = 3 [(google.api.field_behavior) = REQUIRED]; - - // Required. The Configuration specifying where output predictions should - // be written. - BatchPredictOutputConfig output_config = 4 [(google.api.field_behavior) = REQUIRED]; - - // Required. Additional domain-specific parameters for the predictions, any string must - // be up to 25000 characters long. - // - // * For Text Classification: - // - // `score_threshold` - (float) A value from 0.0 to 1.0. When the model - // makes predictions for a text snippet, it will only produce results - // that have at least this confidence score. The default is 0.5. - // - // * For Image Classification: - // - // `score_threshold` - (float) A value from 0.0 to 1.0. When the model - // makes predictions for an image, it will only produce results that - // have at least this confidence score. The default is 0.5. - // - // * For Image Object Detection: - // - // `score_threshold` - (float) When Model detects objects on the image, - // it will only produce bounding boxes which have at least this - // confidence score. Value in 0 to 1 range, default is 0.5. - // `max_bounding_box_count` - (int64) No more than this number of bounding - // boxes will be produced per image. Default is 100, the - // requested value may be limited by server. - // - // * For Video Classification : - // - // `score_threshold` - (float) A value from 0.0 to 1.0. When the model - // makes predictions for a video, it will only produce results that - // have at least this confidence score. The default is 0.5. - // `segment_classification` - (boolean) Set to true to request - // segment-level classification. AutoML Video Intelligence returns - // labels and their confidence scores for the entire segment of the - // video that user specified in the request configuration. - // The default is "true". - // `shot_classification` - (boolean) Set to true to request shot-level - // classification. AutoML Video Intelligence determines the boundaries - // for each camera shot in the entire segment of the video that user - // specified in the request configuration. AutoML Video Intelligence - // then returns labels and their confidence scores for each detected - // shot, along with the start and end time of the shot. - // WARNING: Model evaluation is not done for this classification type, - // the quality of it depends on training data, but there are no metrics - // provided to describe that quality. The default is "false". - // `1s_interval_classification` - (boolean) Set to true to request - // classification for a video at one-second intervals. AutoML Video - // Intelligence returns labels and their confidence scores for each - // second of the entire segment of the video that user specified in the - // request configuration. - // WARNING: Model evaluation is not done for this classification - // type, the quality of it depends on training data, but there are no - // metrics provided to describe that quality. The default is - // "false". - // - // * For Tables: - // - // feature_importance - (boolean) Whether feature importance - // should be populated in the returned TablesAnnotations. The - // default is false. - // - // * For Video Object Tracking: - // - // `score_threshold` - (float) When Model detects objects on video frames, - // it will only produce bounding boxes which have at least this - // confidence score. Value in 0 to 1 range, default is 0.5. - // `max_bounding_box_count` - (int64) No more than this number of bounding - // boxes will be returned per frame. Default is 100, the requested - // value may be limited by server. - // `min_bounding_box_size` - (float) Only bounding boxes with shortest edge - // at least that long as a relative value of video frame size will be - // returned. Value in 0 to 1 range. Default is 0. - map params = 5 [(google.api.field_behavior) = REQUIRED]; -} - -// Result of the Batch Predict. This message is returned in -// [response][google.longrunning.Operation.response] of the operation returned -// by the [PredictionService.BatchPredict][google.cloud.automl.v1beta1.PredictionService.BatchPredict]. -message BatchPredictResult { - // Additional domain-specific prediction response metadata. - // - // * For Image Object Detection: - // `max_bounding_box_count` - (int64) At most that many bounding boxes per - // image could have been returned. - // - // * For Video Object Tracking: - // `max_bounding_box_count` - (int64) At most that many bounding boxes per - // frame could have been returned. - map metadata = 1; -} diff --git a/google/cloud/automl_v1beta1/proto/ranges.proto b/google/cloud/automl_v1beta1/proto/ranges.proto deleted file mode 100644 index 89572bb0..00000000 --- a/google/cloud/automl_v1beta1/proto/ranges.proto +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "RangesProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A range between two double numbers. -message DoubleRange { - // Start of the range, inclusive. - double start = 1; - - // End of the range, exclusive. - double end = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/regression.proto b/google/cloud/automl_v1beta1/proto/regression.proto deleted file mode 100644 index 1286d3d8..00000000 --- a/google/cloud/automl_v1beta1/proto/regression.proto +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_outer_classname = "RegressionProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Metrics for regression problems. -message RegressionEvaluationMetrics { - // Output only. Root Mean Squared Error (RMSE). - float root_mean_squared_error = 1; - - // Output only. Mean Absolute Error (MAE). - float mean_absolute_error = 2; - - // Output only. Mean absolute percentage error. Only set if all ground truth - // values are are positive. - float mean_absolute_percentage_error = 3; - - // Output only. R squared. - float r_squared = 4; - - // Output only. Root mean squared log error. - float root_mean_squared_log_error = 5; -} diff --git a/google/cloud/automl_v1beta1/proto/service.proto b/google/cloud/automl_v1beta1/proto/service.proto deleted file mode 100644 index a421ece1..00000000 --- a/google/cloud/automl_v1beta1/proto/service.proto +++ /dev/null @@ -1,800 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/annotation_payload.proto"; -import "google/cloud/automl/v1beta1/annotation_spec.proto"; -import "google/cloud/automl/v1beta1/column_spec.proto"; -import "google/cloud/automl/v1beta1/dataset.proto"; -import "google/cloud/automl/v1beta1/image.proto"; -import "google/cloud/automl/v1beta1/io.proto"; -import "google/cloud/automl/v1beta1/model.proto"; -import "google/cloud/automl/v1beta1/model_evaluation.proto"; -import "google/cloud/automl/v1beta1/operations.proto"; -import "google/cloud/automl/v1beta1/table_spec.proto"; -import "google/longrunning/operations.proto"; -import "google/protobuf/field_mask.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "AutoMlProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// AutoML Server API. -// -// The resource names are assigned by the server. -// The server never reuses names that it has created after the resources with -// those names are deleted. -// -// An ID of a resource is the last element of the item's resource name. For -// `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}`, then -// the id for the item is `{dataset_id}`. -// -// Currently the only supported `location_id` is "us-central1". -// -// On any input that is documented to expect a string parameter in -// snake_case or kebab-case, either of those cases is accepted. -service AutoMl { - option (google.api.default_host) = "automl.googleapis.com"; - option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; - - // Creates a dataset. - rpc CreateDataset(CreateDatasetRequest) returns (Dataset) { - option (google.api.http) = { - post: "/v1beta1/{parent=projects/*/locations/*}/datasets" - body: "dataset" - }; - option (google.api.method_signature) = "parent,dataset"; - } - - // Gets a dataset. - rpc GetDataset(GetDatasetRequest) returns (Dataset) { - option (google.api.http) = { - get: "/v1beta1/{name=projects/*/locations/*/datasets/*}" - }; - option (google.api.method_signature) = "name"; - } - - // Lists datasets in a project. - rpc ListDatasets(ListDatasetsRequest) returns (ListDatasetsResponse) { - option (google.api.http) = { - get: "/v1beta1/{parent=projects/*/locations/*}/datasets" - }; - option (google.api.method_signature) = "parent"; - } - - // Updates a dataset. - rpc UpdateDataset(UpdateDatasetRequest) returns (Dataset) { - option (google.api.http) = { - patch: "/v1beta1/{dataset.name=projects/*/locations/*/datasets/*}" - body: "dataset" - }; - option (google.api.method_signature) = "dataset"; - } - - // Deletes a dataset and all of its contents. - // Returns empty response in the - // [response][google.longrunning.Operation.response] field when it completes, - // and `delete_details` in the - // [metadata][google.longrunning.Operation.metadata] field. - rpc DeleteDataset(DeleteDatasetRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - delete: "/v1beta1/{name=projects/*/locations/*/datasets/*}" - }; - option (google.api.method_signature) = "name"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Imports data into a dataset. - // For Tables this method can only be called on an empty Dataset. - // - // For Tables: - // * A - // [schema_inference_version][google.cloud.automl.v1beta1.InputConfig.params] - // parameter must be explicitly set. - // Returns an empty response in the - // [response][google.longrunning.Operation.response] field when it completes. - rpc ImportData(ImportDataRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/datasets/*}:importData" - body: "*" - }; - option (google.api.method_signature) = "name,input_config"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Exports dataset's data to the provided output location. - // Returns an empty response in the - // [response][google.longrunning.Operation.response] field when it completes. - rpc ExportData(ExportDataRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/datasets/*}:exportData" - body: "*" - }; - option (google.api.method_signature) = "name,output_config"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Gets an annotation spec. - rpc GetAnnotationSpec(GetAnnotationSpecRequest) returns (AnnotationSpec) { - option (google.api.http) = { - get: "/v1beta1/{name=projects/*/locations/*/datasets/*/annotationSpecs/*}" - }; - option (google.api.method_signature) = "name"; - } - - // Gets a table spec. - rpc GetTableSpec(GetTableSpecRequest) returns (TableSpec) { - option (google.api.http) = { - get: "/v1beta1/{name=projects/*/locations/*/datasets/*/tableSpecs/*}" - }; - option (google.api.method_signature) = "name"; - } - - // Lists table specs in a dataset. - rpc ListTableSpecs(ListTableSpecsRequest) returns (ListTableSpecsResponse) { - option (google.api.http) = { - get: "/v1beta1/{parent=projects/*/locations/*/datasets/*}/tableSpecs" - }; - option (google.api.method_signature) = "parent"; - } - - // Updates a table spec. - rpc UpdateTableSpec(UpdateTableSpecRequest) returns (TableSpec) { - option (google.api.http) = { - patch: "/v1beta1/{table_spec.name=projects/*/locations/*/datasets/*/tableSpecs/*}" - body: "table_spec" - }; - option (google.api.method_signature) = "table_spec"; - } - - // Gets a column spec. - rpc GetColumnSpec(GetColumnSpecRequest) returns (ColumnSpec) { - option (google.api.http) = { - get: "/v1beta1/{name=projects/*/locations/*/datasets/*/tableSpecs/*/columnSpecs/*}" - }; - option (google.api.method_signature) = "name"; - } - - // Lists column specs in a table spec. - rpc ListColumnSpecs(ListColumnSpecsRequest) returns (ListColumnSpecsResponse) { - option (google.api.http) = { - get: "/v1beta1/{parent=projects/*/locations/*/datasets/*/tableSpecs/*}/columnSpecs" - }; - option (google.api.method_signature) = "parent"; - } - - // Updates a column spec. - rpc UpdateColumnSpec(UpdateColumnSpecRequest) returns (ColumnSpec) { - option (google.api.http) = { - patch: "/v1beta1/{column_spec.name=projects/*/locations/*/datasets/*/tableSpecs/*/columnSpecs/*}" - body: "column_spec" - }; - option (google.api.method_signature) = "column_spec"; - } - - // Creates a model. - // Returns a Model in the [response][google.longrunning.Operation.response] - // field when it completes. - // When you create a model, several model evaluations are created for it: - // a global evaluation, and one evaluation for each annotation spec. - rpc CreateModel(CreateModelRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{parent=projects/*/locations/*}/models" - body: "model" - }; - option (google.api.method_signature) = "parent,model"; - option (google.longrunning.operation_info) = { - response_type: "Model" - metadata_type: "OperationMetadata" - }; - } - - // Gets a model. - rpc GetModel(GetModelRequest) returns (Model) { - option (google.api.http) = { - get: "/v1beta1/{name=projects/*/locations/*/models/*}" - }; - option (google.api.method_signature) = "name"; - } - - // Lists models. - rpc ListModels(ListModelsRequest) returns (ListModelsResponse) { - option (google.api.http) = { - get: "/v1beta1/{parent=projects/*/locations/*}/models" - }; - option (google.api.method_signature) = "parent"; - } - - // Deletes a model. - // Returns `google.protobuf.Empty` in the - // [response][google.longrunning.Operation.response] field when it completes, - // and `delete_details` in the - // [metadata][google.longrunning.Operation.metadata] field. - rpc DeleteModel(DeleteModelRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - delete: "/v1beta1/{name=projects/*/locations/*/models/*}" - }; - option (google.api.method_signature) = "name"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Deploys a model. If a model is already deployed, deploying it with the - // same parameters has no effect. Deploying with different parametrs - // (as e.g. changing - // - // [node_number][google.cloud.automl.v1beta1.ImageObjectDetectionModelDeploymentMetadata.node_number]) - // will reset the deployment state without pausing the model's availability. - // - // Only applicable for Text Classification, Image Object Detection , Tables, and Image Segmentation; all other domains manage - // deployment automatically. - // - // Returns an empty response in the - // [response][google.longrunning.Operation.response] field when it completes. - rpc DeployModel(DeployModelRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/models/*}:deploy" - body: "*" - }; - option (google.api.method_signature) = "name"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Undeploys a model. If the model is not deployed this method has no effect. - // - // Only applicable for Text Classification, Image Object Detection and Tables; - // all other domains manage deployment automatically. - // - // Returns an empty response in the - // [response][google.longrunning.Operation.response] field when it completes. - rpc UndeployModel(UndeployModelRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/models/*}:undeploy" - body: "*" - }; - option (google.api.method_signature) = "name"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Exports a trained, "export-able", model to a user specified Google Cloud - // Storage location. A model is considered export-able if and only if it has - // an export format defined for it in - // - // [ModelExportOutputConfig][google.cloud.automl.v1beta1.ModelExportOutputConfig]. - // - // Returns an empty response in the - // [response][google.longrunning.Operation.response] field when it completes. - rpc ExportModel(ExportModelRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/models/*}:export" - body: "*" - }; - option (google.api.method_signature) = "name,output_config"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Exports examples on which the model was evaluated (i.e. which were in the - // TEST set of the dataset the model was created from), together with their - // ground truth annotations and the annotations created (predicted) by the - // model. - // The examples, ground truth and predictions are exported in the state - // they were at the moment the model was evaluated. - // - // This export is available only for 30 days since the model evaluation is - // created. - // - // Currently only available for Tables. - // - // Returns an empty response in the - // [response][google.longrunning.Operation.response] field when it completes. - rpc ExportEvaluatedExamples(ExportEvaluatedExamplesRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/models/*}:exportEvaluatedExamples" - body: "*" - }; - option (google.api.method_signature) = "name,output_config"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Gets a model evaluation. - rpc GetModelEvaluation(GetModelEvaluationRequest) returns (ModelEvaluation) { - option (google.api.http) = { - get: "/v1beta1/{name=projects/*/locations/*/models/*/modelEvaluations/*}" - }; - option (google.api.method_signature) = "name"; - } - - // Lists model evaluations. - rpc ListModelEvaluations(ListModelEvaluationsRequest) returns (ListModelEvaluationsResponse) { - option (google.api.http) = { - get: "/v1beta1/{parent=projects/*/locations/*/models/*}/modelEvaluations" - }; - option (google.api.method_signature) = "parent"; - } -} - -// Request message for [AutoMl.CreateDataset][google.cloud.automl.v1beta1.AutoMl.CreateDataset]. -message CreateDatasetRequest { - // Required. The resource name of the project to create the dataset for. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "locations.googleapis.com/Location" - } - ]; - - // Required. The dataset to create. - Dataset dataset = 2 [(google.api.field_behavior) = REQUIRED]; -} - -// Request message for [AutoMl.GetDataset][google.cloud.automl.v1beta1.AutoMl.GetDataset]. -message GetDatasetRequest { - // Required. The resource name of the dataset to retrieve. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Dataset" - } - ]; -} - -// Request message for [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets]. -message ListDatasetsRequest { - // Required. The resource name of the project from which to list datasets. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "locations.googleapis.com/Location" - } - ]; - - // An expression for filtering the results of the request. - // - // * `dataset_metadata` - for existence of the case (e.g. - // image_classification_dataset_metadata:*). Some examples of using the filter are: - // - // * `translation_dataset_metadata:*` --> The dataset has - // translation_dataset_metadata. - string filter = 3; - - // Requested page size. Server may return fewer results than requested. - // If unspecified, server will pick a default size. - int32 page_size = 4; - - // A token identifying a page of results for the server to return - // Typically obtained via - // [ListDatasetsResponse.next_page_token][google.cloud.automl.v1beta1.ListDatasetsResponse.next_page_token] of the previous - // [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets] call. - string page_token = 6; -} - -// Response message for [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets]. -message ListDatasetsResponse { - // The datasets read. - repeated Dataset datasets = 1; - - // A token to retrieve next page of results. - // Pass to [ListDatasetsRequest.page_token][google.cloud.automl.v1beta1.ListDatasetsRequest.page_token] to obtain that page. - string next_page_token = 2; -} - -// Request message for [AutoMl.UpdateDataset][google.cloud.automl.v1beta1.AutoMl.UpdateDataset] -message UpdateDatasetRequest { - // Required. The dataset which replaces the resource on the server. - Dataset dataset = 1 [(google.api.field_behavior) = REQUIRED]; - - // The update mask applies to the resource. - google.protobuf.FieldMask update_mask = 2; -} - -// Request message for [AutoMl.DeleteDataset][google.cloud.automl.v1beta1.AutoMl.DeleteDataset]. -message DeleteDatasetRequest { - // Required. The resource name of the dataset to delete. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Dataset" - } - ]; -} - -// Request message for [AutoMl.ImportData][google.cloud.automl.v1beta1.AutoMl.ImportData]. -message ImportDataRequest { - // Required. Dataset name. Dataset must already exist. All imported - // annotations and examples will be added. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Dataset" - } - ]; - - // Required. The desired input location and its domain specific semantics, - // if any. - InputConfig input_config = 3 [(google.api.field_behavior) = REQUIRED]; -} - -// Request message for [AutoMl.ExportData][google.cloud.automl.v1beta1.AutoMl.ExportData]. -message ExportDataRequest { - // Required. The resource name of the dataset. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Dataset" - } - ]; - - // Required. The desired output location. - OutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; -} - -// Request message for [AutoMl.GetAnnotationSpec][google.cloud.automl.v1beta1.AutoMl.GetAnnotationSpec]. -message GetAnnotationSpecRequest { - // Required. The resource name of the annotation spec to retrieve. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/AnnotationSpec" - } - ]; -} - -// Request message for [AutoMl.GetTableSpec][google.cloud.automl.v1beta1.AutoMl.GetTableSpec]. -message GetTableSpecRequest { - // Required. The resource name of the table spec to retrieve. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/TableSpec" - } - ]; - - // Mask specifying which fields to read. - google.protobuf.FieldMask field_mask = 2; -} - -// Request message for [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs]. -message ListTableSpecsRequest { - // Required. The resource name of the dataset to list table specs from. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Dataset" - } - ]; - - // Mask specifying which fields to read. - google.protobuf.FieldMask field_mask = 2; - - // Filter expression, see go/filtering. - string filter = 3; - - // Requested page size. The server can return fewer results than requested. - // If unspecified, the server will pick a default size. - int32 page_size = 4; - - // A token identifying a page of results for the server to return. - // Typically obtained from the - // [ListTableSpecsResponse.next_page_token][google.cloud.automl.v1beta1.ListTableSpecsResponse.next_page_token] field of the previous - // [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs] call. - string page_token = 6; -} - -// Response message for [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs]. -message ListTableSpecsResponse { - // The table specs read. - repeated TableSpec table_specs = 1; - - // A token to retrieve next page of results. - // Pass to [ListTableSpecsRequest.page_token][google.cloud.automl.v1beta1.ListTableSpecsRequest.page_token] to obtain that page. - string next_page_token = 2; -} - -// Request message for [AutoMl.UpdateTableSpec][google.cloud.automl.v1beta1.AutoMl.UpdateTableSpec] -message UpdateTableSpecRequest { - // Required. The table spec which replaces the resource on the server. - TableSpec table_spec = 1 [(google.api.field_behavior) = REQUIRED]; - - // The update mask applies to the resource. - google.protobuf.FieldMask update_mask = 2; -} - -// Request message for [AutoMl.GetColumnSpec][google.cloud.automl.v1beta1.AutoMl.GetColumnSpec]. -message GetColumnSpecRequest { - // Required. The resource name of the column spec to retrieve. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/ColumnSpec" - } - ]; - - // Mask specifying which fields to read. - google.protobuf.FieldMask field_mask = 2; -} - -// Request message for [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs]. -message ListColumnSpecsRequest { - // Required. The resource name of the table spec to list column specs from. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/TableSpec" - } - ]; - - // Mask specifying which fields to read. - google.protobuf.FieldMask field_mask = 2; - - // Filter expression, see go/filtering. - string filter = 3; - - // Requested page size. The server can return fewer results than requested. - // If unspecified, the server will pick a default size. - int32 page_size = 4; - - // A token identifying a page of results for the server to return. - // Typically obtained from the - // [ListColumnSpecsResponse.next_page_token][google.cloud.automl.v1beta1.ListColumnSpecsResponse.next_page_token] field of the previous - // [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs] call. - string page_token = 6; -} - -// Response message for [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs]. -message ListColumnSpecsResponse { - // The column specs read. - repeated ColumnSpec column_specs = 1; - - // A token to retrieve next page of results. - // Pass to [ListColumnSpecsRequest.page_token][google.cloud.automl.v1beta1.ListColumnSpecsRequest.page_token] to obtain that page. - string next_page_token = 2; -} - -// Request message for [AutoMl.UpdateColumnSpec][google.cloud.automl.v1beta1.AutoMl.UpdateColumnSpec] -message UpdateColumnSpecRequest { - // Required. The column spec which replaces the resource on the server. - ColumnSpec column_spec = 1 [(google.api.field_behavior) = REQUIRED]; - - // The update mask applies to the resource. - google.protobuf.FieldMask update_mask = 2; -} - -// Request message for [AutoMl.CreateModel][google.cloud.automl.v1beta1.AutoMl.CreateModel]. -message CreateModelRequest { - // Required. Resource name of the parent project where the model is being created. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "locations.googleapis.com/Location" - } - ]; - - // Required. The model to create. - Model model = 4 [(google.api.field_behavior) = REQUIRED]; -} - -// Request message for [AutoMl.GetModel][google.cloud.automl.v1beta1.AutoMl.GetModel]. -message GetModelRequest { - // Required. Resource name of the model. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; -} - -// Request message for [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels]. -message ListModelsRequest { - // Required. Resource name of the project, from which to list the models. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "locations.googleapis.com/Location" - } - ]; - - // An expression for filtering the results of the request. - // - // * `model_metadata` - for existence of the case (e.g. - // video_classification_model_metadata:*). - // * `dataset_id` - for = or !=. Some examples of using the filter are: - // - // * `image_classification_model_metadata:*` --> The model has - // image_classification_model_metadata. - // * `dataset_id=5` --> The model was created from a dataset with ID 5. - string filter = 3; - - // Requested page size. - int32 page_size = 4; - - // A token identifying a page of results for the server to return - // Typically obtained via - // [ListModelsResponse.next_page_token][google.cloud.automl.v1beta1.ListModelsResponse.next_page_token] of the previous - // [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels] call. - string page_token = 6; -} - -// Response message for [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels]. -message ListModelsResponse { - // List of models in the requested page. - repeated Model model = 1; - - // A token to retrieve next page of results. - // Pass to [ListModelsRequest.page_token][google.cloud.automl.v1beta1.ListModelsRequest.page_token] to obtain that page. - string next_page_token = 2; -} - -// Request message for [AutoMl.DeleteModel][google.cloud.automl.v1beta1.AutoMl.DeleteModel]. -message DeleteModelRequest { - // Required. Resource name of the model being deleted. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; -} - -// Request message for [AutoMl.DeployModel][google.cloud.automl.v1beta1.AutoMl.DeployModel]. -message DeployModelRequest { - // The per-domain specific deployment parameters. - oneof model_deployment_metadata { - // Model deployment metadata specific to Image Object Detection. - ImageObjectDetectionModelDeploymentMetadata image_object_detection_model_deployment_metadata = 2; - - // Model deployment metadata specific to Image Classification. - ImageClassificationModelDeploymentMetadata image_classification_model_deployment_metadata = 4; - } - - // Required. Resource name of the model to deploy. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; -} - -// Request message for [AutoMl.UndeployModel][google.cloud.automl.v1beta1.AutoMl.UndeployModel]. -message UndeployModelRequest { - // Required. Resource name of the model to undeploy. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; -} - -// Request message for [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]. -// Models need to be enabled for exporting, otherwise an error code will be -// returned. -message ExportModelRequest { - // Required. The resource name of the model to export. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; - - // Required. The desired output location and configuration. - ModelExportOutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; -} - -// Request message for [AutoMl.ExportEvaluatedExamples][google.cloud.automl.v1beta1.AutoMl.ExportEvaluatedExamples]. -message ExportEvaluatedExamplesRequest { - // Required. The resource name of the model whose evaluated examples are to - // be exported. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; - - // Required. The desired output location and configuration. - ExportEvaluatedExamplesOutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; -} - -// Request message for [AutoMl.GetModelEvaluation][google.cloud.automl.v1beta1.AutoMl.GetModelEvaluation]. -message GetModelEvaluationRequest { - // Required. Resource name for the model evaluation. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/ModelEvaluation" - } - ]; -} - -// Request message for [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations]. -message ListModelEvaluationsRequest { - // Required. Resource name of the model to list the model evaluations for. - // If modelId is set as "-", this will list model evaluations from across all - // models of the parent location. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; - - // An expression for filtering the results of the request. - // - // * `annotation_spec_id` - for =, != or existence. See example below for - // the last. - // - // Some examples of using the filter are: - // - // * `annotation_spec_id!=4` --> The model evaluation was done for - // annotation spec with ID different than 4. - // * `NOT annotation_spec_id:*` --> The model evaluation was done for - // aggregate of all annotation specs. - string filter = 3; - - // Requested page size. - int32 page_size = 4; - - // A token identifying a page of results for the server to return. - // Typically obtained via - // [ListModelEvaluationsResponse.next_page_token][google.cloud.automl.v1beta1.ListModelEvaluationsResponse.next_page_token] of the previous - // [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations] call. - string page_token = 6; -} - -// Response message for [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations]. -message ListModelEvaluationsResponse { - // List of model evaluations in the requested page. - repeated ModelEvaluation model_evaluation = 1; - - // A token to retrieve next page of results. - // Pass to the [ListModelEvaluationsRequest.page_token][google.cloud.automl.v1beta1.ListModelEvaluationsRequest.page_token] field of a new - // [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations] request to obtain that page. - string next_page_token = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/table_spec.proto b/google/cloud/automl_v1beta1/proto/table_spec.proto deleted file mode 100644 index bc3fc744..00000000 --- a/google/cloud/automl_v1beta1/proto/table_spec.proto +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/io.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A specification of a relational table. -// The table's schema is represented via its child column specs. It is -// pre-populated as part of ImportData by schema inference algorithm, the -// version of which is a required parameter of ImportData InputConfig. -// Note: While working with a table, at times the schema may be -// inconsistent with the data in the table (e.g. string in a FLOAT64 column). -// The consistency validation is done upon creation of a model. -// Used by: -// * Tables -message TableSpec { - option (google.api.resource) = { - type: "automl.googleapis.com/TableSpec" - pattern: "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}" - }; - - // Output only. The resource name of the table spec. - // Form: - // - // `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/tableSpecs/{table_spec_id}` - string name = 1; - - // column_spec_id of the time column. Only used if the parent dataset's - // ml_use_column_spec_id is not set. Used to split rows into TRAIN, VALIDATE - // and TEST sets such that oldest rows go to TRAIN set, newest to TEST, and - // those in between to VALIDATE. - // Required type: TIMESTAMP. - // If both this column and ml_use_column are not set, then ML use of all rows - // will be assigned by AutoML. NOTE: Updates of this field will instantly - // affect any other users concurrently working with the dataset. - string time_column_spec_id = 2; - - // Output only. The number of rows (i.e. examples) in the table. - int64 row_count = 3; - - // Output only. The number of valid rows (i.e. without values that don't match - // DataType-s of their columns). - int64 valid_row_count = 4; - - // Output only. The number of columns of the table. That is, the number of - // child ColumnSpec-s. - int64 column_count = 7; - - // Output only. Input configs via which data currently residing in the table - // had been imported. - repeated InputConfig input_configs = 5; - - // Used to perform consistent read-modify-write updates. If not set, a blind - // "overwrite" update happens. - string etag = 6; -} diff --git a/google/cloud/automl_v1beta1/proto/tables.proto b/google/cloud/automl_v1beta1/proto/tables.proto deleted file mode 100644 index 5327f5e7..00000000 --- a/google/cloud/automl_v1beta1/proto/tables.proto +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/cloud/automl/v1beta1/column_spec.proto"; -import "google/cloud/automl/v1beta1/data_items.proto"; -import "google/cloud/automl/v1beta1/data_stats.proto"; -import "google/cloud/automl/v1beta1/ranges.proto"; -import "google/cloud/automl/v1beta1/regression.proto"; -import "google/cloud/automl/v1beta1/temporal.proto"; -import "google/protobuf/struct.proto"; -import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Metadata for a dataset used for AutoML Tables. -message TablesDatasetMetadata { - // Output only. The table_spec_id of the primary table of this dataset. - string primary_table_spec_id = 1; - - // column_spec_id of the primary table's column that should be used as the - // training & prediction target. - // This column must be non-nullable and have one of following data types - // (otherwise model creation will error): - // - // * CATEGORY - // - // * FLOAT64 - // - // If the type is CATEGORY , only up to - // 100 unique values may exist in that column across all rows. - // - // NOTE: Updates of this field will instantly affect any other users - // concurrently working with the dataset. - string target_column_spec_id = 2; - - // column_spec_id of the primary table's column that should be used as the - // weight column, i.e. the higher the value the more important the row will be - // during model training. - // Required type: FLOAT64. - // Allowed values: 0 to 10000, inclusive on both ends; 0 means the row is - // ignored for training. - // If not set all rows are assumed to have equal weight of 1. - // NOTE: Updates of this field will instantly affect any other users - // concurrently working with the dataset. - string weight_column_spec_id = 3; - - // column_spec_id of the primary table column which specifies a possible ML - // use of the row, i.e. the column will be used to split the rows into TRAIN, - // VALIDATE and TEST sets. - // Required type: STRING. - // This column, if set, must either have all of `TRAIN`, `VALIDATE`, `TEST` - // among its values, or only have `TEST`, `UNASSIGNED` values. In the latter - // case the rows with `UNASSIGNED` value will be assigned by AutoML. Note - // that if a given ml use distribution makes it impossible to create a "good" - // model, that call will error describing the issue. - // If both this column_spec_id and primary table's time_column_spec_id are not - // set, then all rows are treated as `UNASSIGNED`. - // NOTE: Updates of this field will instantly affect any other users - // concurrently working with the dataset. - string ml_use_column_spec_id = 4; - - // Output only. Correlations between - // - // [TablesDatasetMetadata.target_column_spec_id][google.cloud.automl.v1beta1.TablesDatasetMetadata.target_column_spec_id], - // and other columns of the - // - // [TablesDatasetMetadataprimary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_spec_id]. - // Only set if the target column is set. Mapping from other column spec id to - // its CorrelationStats with the target column. - // This field may be stale, see the stats_update_time field for - // for the timestamp at which these stats were last updated. - map target_column_correlations = 6; - - // Output only. The most recent timestamp when target_column_correlations - // field and all descendant ColumnSpec.data_stats and - // ColumnSpec.top_correlated_columns fields were last (re-)generated. Any - // changes that happened to the dataset afterwards are not reflected in these - // fields values. The regeneration happens in the background on a best effort - // basis. - google.protobuf.Timestamp stats_update_time = 7; -} - -// Model metadata specific to AutoML Tables. -message TablesModelMetadata { - // Additional optimization objective configuration. Required for - // `MAXIMIZE_PRECISION_AT_RECALL` and `MAXIMIZE_RECALL_AT_PRECISION`, - // otherwise unused. - oneof additional_optimization_objective_config { - // Required when optimization_objective is "MAXIMIZE_PRECISION_AT_RECALL". - // Must be between 0 and 1, inclusive. - float optimization_objective_recall_value = 17; - - // Required when optimization_objective is "MAXIMIZE_RECALL_AT_PRECISION". - // Must be between 0 and 1, inclusive. - float optimization_objective_precision_value = 18; - } - - // Column spec of the dataset's primary table's column the model is - // predicting. Snapshotted when model creation started. - // Only 3 fields are used: - // name - May be set on CreateModel, if it's not then the ColumnSpec - // corresponding to the current target_column_spec_id of the dataset - // the model is trained from is used. - // If neither is set, CreateModel will error. - // display_name - Output only. - // data_type - Output only. - ColumnSpec target_column_spec = 2; - - // Column specs of the dataset's primary table's columns, on which - // the model is trained and which are used as the input for predictions. - // The - // - // [target_column][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] - // as well as, according to dataset's state upon model creation, - // - // [weight_column][google.cloud.automl.v1beta1.TablesDatasetMetadata.weight_column_spec_id], - // and - // - // [ml_use_column][google.cloud.automl.v1beta1.TablesDatasetMetadata.ml_use_column_spec_id] - // must never be included here. - // - // Only 3 fields are used: - // - // * name - May be set on CreateModel, if set only the columns specified are - // used, otherwise all primary table's columns (except the ones listed - // above) are used for the training and prediction input. - // - // * display_name - Output only. - // - // * data_type - Output only. - repeated ColumnSpec input_feature_column_specs = 3; - - // Objective function the model is optimizing towards. The training process - // creates a model that maximizes/minimizes the value of the objective - // function over the validation set. - // - // The supported optimization objectives depend on the prediction type. - // If the field is not set, a default objective function is used. - // - // CLASSIFICATION_BINARY: - // "MAXIMIZE_AU_ROC" (default) - Maximize the area under the receiver - // operating characteristic (ROC) curve. - // "MINIMIZE_LOG_LOSS" - Minimize log loss. - // "MAXIMIZE_AU_PRC" - Maximize the area under the precision-recall curve. - // "MAXIMIZE_PRECISION_AT_RECALL" - Maximize precision for a specified - // recall value. - // "MAXIMIZE_RECALL_AT_PRECISION" - Maximize recall for a specified - // precision value. - // - // CLASSIFICATION_MULTI_CLASS : - // "MINIMIZE_LOG_LOSS" (default) - Minimize log loss. - // - // - // REGRESSION: - // "MINIMIZE_RMSE" (default) - Minimize root-mean-squared error (RMSE). - // "MINIMIZE_MAE" - Minimize mean-absolute error (MAE). - // "MINIMIZE_RMSLE" - Minimize root-mean-squared log error (RMSLE). - string optimization_objective = 4; - - // Output only. Auxiliary information for each of the - // input_feature_column_specs with respect to this particular model. - repeated TablesModelColumnInfo tables_model_column_info = 5; - - // Required. The train budget of creating this model, expressed in milli node - // hours i.e. 1,000 value in this field means 1 node hour. - // - // The training cost of the model will not exceed this budget. The final cost - // will be attempted to be close to the budget, though may end up being (even) - // noticeably smaller - at the backend's discretion. This especially may - // happen when further model training ceases to provide any improvements. - // - // If the budget is set to a value known to be insufficient to train a - // model for the given dataset, the training won't be attempted and - // will error. - // - // The train budget must be between 1,000 and 72,000 milli node hours, - // inclusive. - int64 train_budget_milli_node_hours = 6; - - // Output only. The actual training cost of the model, expressed in milli - // node hours, i.e. 1,000 value in this field means 1 node hour. Guaranteed - // to not exceed the train budget. - int64 train_cost_milli_node_hours = 7; - - // Use the entire training budget. This disables the early stopping feature. - // By default, the early stopping feature is enabled, which means that AutoML - // Tables might stop training before the entire training budget has been used. - bool disable_early_stopping = 12; -} - -// Contains annotation details specific to Tables. -message TablesAnnotation { - // Output only. A confidence estimate between 0.0 and 1.0, inclusive. A higher - // value means greater confidence in the returned value. - // For - // - // [target_column_spec][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] - // of FLOAT64 data type the score is not populated. - float score = 1; - - // Output only. Only populated when - // - // [target_column_spec][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] - // has FLOAT64 data type. An interval in which the exactly correct target - // value has 95% chance to be in. - DoubleRange prediction_interval = 4; - - // The predicted value of the row's - // - // [target_column][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec]. - // The value depends on the column's DataType: - // - // * CATEGORY - the predicted (with the above confidence `score`) CATEGORY - // value. - // - // * FLOAT64 - the predicted (with above `prediction_interval`) FLOAT64 value. - google.protobuf.Value value = 2; - - // Output only. Auxiliary information for each of the model's - // - // [input_feature_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] - // with respect to this particular prediction. - // If no other fields than - // - // [column_spec_name][google.cloud.automl.v1beta1.TablesModelColumnInfo.column_spec_name] - // and - // - // [column_display_name][google.cloud.automl.v1beta1.TablesModelColumnInfo.column_display_name] - // would be populated, then this whole field is not. - repeated TablesModelColumnInfo tables_model_column_info = 3; - - // Output only. Stores the prediction score for the baseline example, which - // is defined as the example with all values set to their baseline values. - // This is used as part of the Sampled Shapley explanation of the model's - // prediction. This field is populated only when feature importance is - // requested. For regression models, this holds the baseline prediction for - // the baseline example. For classification models, this holds the baseline - // prediction for the baseline example for the argmax class. - float baseline_score = 5; -} - -// An information specific to given column and Tables Model, in context -// of the Model and the predictions created by it. -message TablesModelColumnInfo { - // Output only. The name of the ColumnSpec describing the column. Not - // populated when this proto is outputted to BigQuery. - string column_spec_name = 1; - - // Output only. The display name of the column (same as the display_name of - // its ColumnSpec). - string column_display_name = 2; - - // Output only. When given as part of a Model (always populated): - // Measurement of how much model predictions correctness on the TEST data - // depend on values in this column. A value between 0 and 1, higher means - // higher influence. These values are normalized - for all input feature - // columns of a given model they add to 1. - // - // When given back by Predict (populated iff - // [feature_importance - // param][google.cloud.automl.v1beta1.PredictRequest.params] is set) or Batch - // Predict (populated iff - // [feature_importance][google.cloud.automl.v1beta1.PredictRequest.params] - // param is set): - // Measurement of how impactful for the prediction returned for the given row - // the value in this column was. Specifically, the feature importance - // specifies the marginal contribution that the feature made to the prediction - // score compared to the baseline score. These values are computed using the - // Sampled Shapley method. - float feature_importance = 3; -} diff --git a/google/cloud/automl_v1beta1/proto/temporal.proto b/google/cloud/automl_v1beta1/proto/temporal.proto deleted file mode 100644 index 76db8887..00000000 --- a/google/cloud/automl_v1beta1/proto/temporal.proto +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/protobuf/duration.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A time period inside of an example that has a time dimension (e.g. video). -message TimeSegment { - // Start of the time segment (inclusive), represented as the duration since - // the example start. - google.protobuf.Duration start_time_offset = 1; - - // End of the time segment (exclusive), represented as the duration since the - // example start. - google.protobuf.Duration end_time_offset = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/text.proto b/google/cloud/automl_v1beta1/proto/text.proto deleted file mode 100644 index f6f33185..00000000 --- a/google/cloud/automl_v1beta1/proto/text.proto +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "TextProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Dataset metadata for classification. -message TextClassificationDatasetMetadata { - // Required. Type of the classification problem. - ClassificationType classification_type = 1; -} - -// Model metadata that is specific to text classification. -message TextClassificationModelMetadata { - // Output only. Classification type of the dataset used to train this model. - ClassificationType classification_type = 3; -} - -// Dataset metadata that is specific to text extraction -message TextExtractionDatasetMetadata { - -} - -// Model metadata that is specific to text extraction. -message TextExtractionModelMetadata { - -} - -// Dataset metadata for text sentiment. -message TextSentimentDatasetMetadata { - // Required. A sentiment is expressed as an integer ordinal, where higher value - // means a more positive sentiment. The range of sentiments that will be used - // is between 0 and sentiment_max (inclusive on both ends), and all the values - // in the range must be represented in the dataset before a model can be - // created. - // sentiment_max value must be between 1 and 10 (inclusive). - int32 sentiment_max = 1; -} - -// Model metadata that is specific to text sentiment. -message TextSentimentModelMetadata { - -} diff --git a/google/cloud/automl_v1beta1/proto/text_extraction.proto b/google/cloud/automl_v1beta1/proto/text_extraction.proto deleted file mode 100644 index cfb0e0b3..00000000 --- a/google/cloud/automl_v1beta1/proto/text_extraction.proto +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/text_segment.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Annotation for identifying spans of text. -message TextExtractionAnnotation { - // Required. Text extraction annotations can either be a text segment or a - // text relation. - oneof annotation { - // An entity annotation will set this, which is the part of the original - // text to which the annotation pertains. - TextSegment text_segment = 3; - } - - // Output only. A confidence estimate between 0.0 and 1.0. A higher value - // means greater confidence in correctness of the annotation. - float score = 1; -} - -// Model evaluation metrics for text extraction problems. -message TextExtractionEvaluationMetrics { - // Metrics for a single confidence threshold. - message ConfidenceMetricsEntry { - // Output only. The confidence threshold value used to compute the metrics. - // Only annotations with score of at least this threshold are considered to - // be ones the model would return. - float confidence_threshold = 1; - - // Output only. Recall under the given confidence threshold. - float recall = 3; - - // Output only. Precision under the given confidence threshold. - float precision = 4; - - // Output only. The harmonic mean of recall and precision. - float f1_score = 5; - } - - // Output only. The Area under precision recall curve metric. - float au_prc = 1; - - // Output only. Metrics that have confidence thresholds. - // Precision-recall curve can be derived from it. - repeated ConfidenceMetricsEntry confidence_metrics_entries = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/text_segment.proto b/google/cloud/automl_v1beta1/proto/text_segment.proto deleted file mode 100644 index 94b17d93..00000000 --- a/google/cloud/automl_v1beta1/proto/text_segment.proto +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "TextSegmentProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A contiguous part of a text (string), assuming it has an UTF-8 NFC encoding. -message TextSegment { - // Output only. The content of the TextSegment. - string content = 3; - - // Required. Zero-based character index of the first character of the text - // segment (counting characters from the beginning of the text). - int64 start_offset = 1; - - // Required. Zero-based character index of the first character past the end of - // the text segment (counting character from the beginning of the text). - // The character at the end_offset is NOT included in the text segment. - int64 end_offset = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/text_sentiment.proto b/google/cloud/automl_v1beta1/proto/text_sentiment.proto deleted file mode 100644 index 5444c52b..00000000 --- a/google/cloud/automl_v1beta1/proto/text_sentiment.proto +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_outer_classname = "TextSentimentProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Contains annotation details specific to text sentiment. -message TextSentimentAnnotation { - // Output only. The sentiment with the semantic, as given to the - // [AutoMl.ImportData][google.cloud.automl.v1beta1.AutoMl.ImportData] when populating the dataset from which the model used - // for the prediction had been trained. - // The sentiment values are between 0 and - // Dataset.text_sentiment_dataset_metadata.sentiment_max (inclusive), - // with higher value meaning more positive sentiment. They are completely - // relative, i.e. 0 means least positive sentiment and sentiment_max means - // the most positive from the sentiments present in the train data. Therefore - // e.g. if train data had only negative sentiment, then sentiment_max, would - // be still negative (although least negative). - // The sentiment shouldn't be confused with "score" or "magnitude" - // from the previous Natural Language Sentiment Analysis API. - int32 sentiment = 1; -} - -// Model evaluation metrics for text sentiment problems. -message TextSentimentEvaluationMetrics { - // Output only. Precision. - float precision = 1; - - // Output only. Recall. - float recall = 2; - - // Output only. The harmonic mean of recall and precision. - float f1_score = 3; - - // Output only. Mean absolute error. Only set for the overall model - // evaluation, not for evaluation of a single annotation spec. - float mean_absolute_error = 4; - - // Output only. Mean squared error. Only set for the overall model - // evaluation, not for evaluation of a single annotation spec. - float mean_squared_error = 5; - - // Output only. Linear weighted kappa. Only set for the overall model - // evaluation, not for evaluation of a single annotation spec. - float linear_kappa = 6; - - // Output only. Quadratic weighted kappa. Only set for the overall model - // evaluation, not for evaluation of a single annotation spec. - float quadratic_kappa = 7; - - // Output only. Confusion matrix of the evaluation. - // Only set for the overall model evaluation, not for evaluation of a single - // annotation spec. - ClassificationEvaluationMetrics.ConfusionMatrix confusion_matrix = 8; - - // Output only. The annotation spec ids used for this evaluation. - // Deprecated . - repeated string annotation_spec_id = 9 [deprecated = true]; -} diff --git a/google/cloud/automl_v1beta1/proto/translation.proto b/google/cloud/automl_v1beta1/proto/translation.proto deleted file mode 100644 index 8585bd41..00000000 --- a/google/cloud/automl_v1beta1/proto/translation.proto +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/field_behavior.proto"; -import "google/cloud/automl/v1beta1/data_items.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "TranslationProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Dataset metadata that is specific to translation. -message TranslationDatasetMetadata { - // Required. The BCP-47 language code of the source language. - string source_language_code = 1 [(google.api.field_behavior) = REQUIRED]; - - // Required. The BCP-47 language code of the target language. - string target_language_code = 2 [(google.api.field_behavior) = REQUIRED]; -} - -// Evaluation metrics for the dataset. -message TranslationEvaluationMetrics { - // Output only. BLEU score. - double bleu_score = 1; - - // Output only. BLEU score for base model. - double base_bleu_score = 2; -} - -// Model metadata that is specific to translation. -message TranslationModelMetadata { - // The resource name of the model to use as a baseline to train the custom - // model. If unset, we use the default base model provided by Google - // Translate. Format: - // `projects/{project_id}/locations/{location_id}/models/{model_id}` - string base_model = 1; - - // Output only. Inferred from the dataset. - // The source languge (The BCP-47 language code) that is used for training. - string source_language_code = 2; - - // Output only. The target languge (The BCP-47 language code) that is used for - // training. - string target_language_code = 3; -} - -// Annotation details specific to translation. -message TranslationAnnotation { - // Output only . The translated content. - TextSnippet translated_content = 1; -} diff --git a/google/cloud/automl_v1beta1/proto/video.proto b/google/cloud/automl_v1beta1/proto/video.proto deleted file mode 100644 index 268ae2a8..00000000 --- a/google/cloud/automl_v1beta1/proto/video.proto +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "VideoProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Dataset metadata specific to video classification. -// All Video Classification datasets are treated as multi label. -message VideoClassificationDatasetMetadata { - -} - -// Dataset metadata specific to video object tracking. -message VideoObjectTrackingDatasetMetadata { - -} - -// Model metadata specific to video classification. -message VideoClassificationModelMetadata { - -} - -// Model metadata specific to video object tracking. -message VideoObjectTrackingModelMetadata { - -} diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index 1d9cb516..5c6d1f5b 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -87,14 +87,13 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT - column_spec_path = staticmethod(AutoMlClient.column_spec_path) - parse_column_spec_path = staticmethod(AutoMlClient.parse_column_spec_path) dataset_path = staticmethod(AutoMlClient.dataset_path) - parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) + model_path = staticmethod(AutoMlClient.model_path) - parse_model_path = staticmethod(AutoMlClient.parse_model_path) + + column_spec_path = staticmethod(AutoMlClient.column_spec_path) + table_spec_path = staticmethod(AutoMlClient.table_spec_path) - parse_table_spec_path = staticmethod(AutoMlClient.parse_table_spec_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file @@ -125,19 +124,16 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1beta1/services/auto_ml/client.py b/google/cloud/automl_v1beta1/services/auto_ml/client.py index dd44b58e..9416b524 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/client.py @@ -16,7 +16,6 @@ # from collections import OrderedDict -from distutils import util import os import re from typing import Callable, Dict, Sequence, Tuple, Type, Union @@ -28,7 +27,6 @@ from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore @@ -265,19 +263,16 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -293,43 +288,25 @@ def __init__( if client_options is None: client_options = ClientOptions.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) - ) - - ssl_credentials = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - is_mtls = True - else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if client_options.api_endpoint is None: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT + client_options.api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT + client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT + has_client_cert_source = ( + client_options.client_cert_source is not None + or mtls.has_default_client_cert_source() + ) + client_options.api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if has_client_cert_source + else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -353,9 +330,10 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=api_endpoint, + host=client_options.api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + api_mtls_endpoint=client_options.api_endpoint, + client_cert_source=client_options.client_cert_source, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py index 642c9f7b..d50f2201 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth # type: ignore +from google import auth from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py index a8cb2fd7..a3c183e4 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py @@ -15,7 +15,6 @@ # limitations under the License. # -import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -25,6 +24,7 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore + import grpc # type: ignore from google.cloud.automl_v1beta1.types import annotation_spec @@ -81,7 +81,6 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -102,16 +101,14 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -134,11 +131,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -169,23 +161,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) self._stubs = {} # type: Dict[str, Callable] @@ -251,6 +226,13 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py index a977ad45..c8d24dad 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py @@ -15,13 +15,11 @@ # limitations under the License. # -import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -125,7 +123,6 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -147,16 +144,14 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -179,22 +174,12 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -214,23 +199,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) # Run the base constructor. super().__init__( @@ -251,6 +219,13 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py index 3974a08c..cd313402 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py @@ -82,19 +82,16 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1beta1/services/prediction_service/client.py b/google/cloud/automl_v1beta1/services/prediction_service/client.py index 747f4c4b..81cb0649 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/client.py @@ -16,7 +16,6 @@ # from collections import OrderedDict -from distutils import util import os import re from typing import Callable, Dict, Sequence, Tuple, Type, Union @@ -28,7 +27,6 @@ from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore @@ -163,19 +161,16 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -191,43 +186,25 @@ def __init__( if client_options is None: client_options = ClientOptions.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) - ) - - ssl_credentials = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - is_mtls = True - else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if client_options.api_endpoint is None: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT + client_options.api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT + client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT + has_client_cert_source = ( + client_options.client_cert_source is not None + or mtls.has_default_client_cert_source() + ) + client_options.api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if has_client_cert_source + else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -251,9 +228,10 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=api_endpoint, + host=client_options.api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + api_mtls_endpoint=client_options.api_endpoint, + client_cert_source=client_options.client_cert_source, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py index 04857f4c..bb674eca 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth # type: ignore +from google import auth from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py index 3c484247..9bc30cdd 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py @@ -15,7 +15,6 @@ # limitations under the License. # -import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -25,6 +24,7 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore + import grpc # type: ignore from google.cloud.automl_v1beta1.types import prediction_service @@ -61,7 +61,6 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -82,16 +81,14 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -114,11 +111,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -149,23 +141,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) self._stubs = {} # type: Dict[str, Callable] @@ -231,6 +206,13 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py index 0b1bb638..2c7d9712 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py @@ -15,13 +15,11 @@ # limitations under the License. # -import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -105,7 +103,6 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -127,16 +124,14 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -159,22 +154,12 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -194,23 +179,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) # Run the base constructor. super().__init__( @@ -231,6 +199,13 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/noxfile.py b/noxfile.py index 709afdde..9c69b3b7 100644 --- a/noxfile.py +++ b/noxfile.py @@ -74,6 +74,7 @@ def default(session): session.install("mock", "pytest", "pytest-cov") session.install("-e", ".[pandas,storage]") + session.install("proto-plus==1.8.1") # Run py.test against the unit tests. session.run( @@ -198,3 +199,36 @@ def docfx(session): os.path.join("docs", ""), os.path.join("docs", "_build", "html", ""), ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docfx(session): + """Build the docfx yaml files for this library.""" + + session.install("-e", ".[pandas,storage]") + session.install("sphinx<3.0.0", "alabaster", "recommonmark", "sphinx-docfx-yaml") + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-D", + ( + "extensions=sphinx.ext.autodoc," + "sphinx.ext.autosummary," + "docfx_yaml.extension," + "sphinx.ext.intersphinx," + "sphinx.ext.coverage," + "sphinx.ext.napoleon," + "sphinx.ext.todo," + "sphinx.ext.viewcode," + "recommonmark" + ), + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) diff --git a/synth.metadata b/synth.metadata index 28cf6035..6c3bc216 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,16 +3,16 @@ { "git": { "name": ".", - "remote": "https://github.com/googleapis/python-automl.git", - "sha": "8c7d54872a6e5628171f160e1a39a067d5f46563" + "remote": "git@github.com:googleapis/python-automl", + "sha": "9b218b1f1cd0caef664e51064baf5f4af07a97c1" } }, { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "877aadc6daf8968e8a1122cf1186623d11d8bd46", - "internalRef": "332039388" + "sha": "17de2b31f9450385e739bedeeaac6e1ec4f239a8", + "internalRef": "327504150" } }, { @@ -49,221 +49,5 @@ "generator": "bazel" } } - ], - "generatedFiles": [ - ".coveragerc", - ".flake8", - ".github/CONTRIBUTING.md", - ".github/ISSUE_TEMPLATE/bug_report.md", - ".github/ISSUE_TEMPLATE/feature_request.md", - ".github/ISSUE_TEMPLATE/support_request.md", - ".github/PULL_REQUEST_TEMPLATE.md", - ".github/release-please.yml", - ".gitignore", - ".kokoro/build.sh", - ".kokoro/continuous/common.cfg", - ".kokoro/continuous/continuous.cfg", - ".kokoro/docker/docs/Dockerfile", - ".kokoro/docker/docs/fetch_gpg_keys.sh", - ".kokoro/docs/common.cfg", - ".kokoro/docs/docs-presubmit.cfg", - ".kokoro/docs/docs.cfg", - ".kokoro/presubmit/common.cfg", - ".kokoro/presubmit/presubmit.cfg", - ".kokoro/publish-docs.sh", - ".kokoro/release.sh", - ".kokoro/release/common.cfg", - ".kokoro/release/release.cfg", - ".kokoro/samples/lint/common.cfg", - ".kokoro/samples/lint/continuous.cfg", - ".kokoro/samples/lint/periodic.cfg", - ".kokoro/samples/lint/presubmit.cfg", - ".kokoro/samples/python3.6/common.cfg", - ".kokoro/samples/python3.6/continuous.cfg", - ".kokoro/samples/python3.6/periodic.cfg", - ".kokoro/samples/python3.6/presubmit.cfg", - ".kokoro/samples/python3.7/common.cfg", - ".kokoro/samples/python3.7/continuous.cfg", - ".kokoro/samples/python3.7/periodic.cfg", - ".kokoro/samples/python3.7/presubmit.cfg", - ".kokoro/samples/python3.8/common.cfg", - ".kokoro/samples/python3.8/continuous.cfg", - ".kokoro/samples/python3.8/periodic.cfg", - ".kokoro/samples/python3.8/presubmit.cfg", - ".kokoro/test-samples.sh", - ".kokoro/trampoline.sh", - ".kokoro/trampoline_v2.sh", - ".trampolinerc", - "CODE_OF_CONDUCT.md", - "CONTRIBUTING.rst", - "LICENSE", - "MANIFEST.in", - "docs/_static/custom.css", - "docs/_templates/layout.html", - "docs/automl_v1/services.rst", - "docs/automl_v1/types.rst", - "docs/automl_v1beta1/services.rst", - "docs/automl_v1beta1/types.rst", - "docs/conf.py", - "docs/multiprocessing.rst", - "google/cloud/automl/__init__.py", - "google/cloud/automl/py.typed", - "google/cloud/automl_v1/__init__.py", - "google/cloud/automl_v1/proto/annotation_payload.proto", - "google/cloud/automl_v1/proto/annotation_spec.proto", - "google/cloud/automl_v1/proto/classification.proto", - "google/cloud/automl_v1/proto/data_items.proto", - "google/cloud/automl_v1/proto/dataset.proto", - "google/cloud/automl_v1/proto/detection.proto", - "google/cloud/automl_v1/proto/geometry.proto", - "google/cloud/automl_v1/proto/image.proto", - "google/cloud/automl_v1/proto/io.proto", - "google/cloud/automl_v1/proto/model.proto", - "google/cloud/automl_v1/proto/model_evaluation.proto", - "google/cloud/automl_v1/proto/operations.proto", - "google/cloud/automl_v1/proto/prediction_service.proto", - "google/cloud/automl_v1/proto/service.proto", - "google/cloud/automl_v1/proto/text.proto", - "google/cloud/automl_v1/proto/text_extraction.proto", - "google/cloud/automl_v1/proto/text_segment.proto", - "google/cloud/automl_v1/proto/text_sentiment.proto", - "google/cloud/automl_v1/proto/translation.proto", - "google/cloud/automl_v1/py.typed", - "google/cloud/automl_v1/services/__init__.py", - "google/cloud/automl_v1/services/auto_ml/__init__.py", - "google/cloud/automl_v1/services/auto_ml/async_client.py", - "google/cloud/automl_v1/services/auto_ml/client.py", - "google/cloud/automl_v1/services/auto_ml/pagers.py", - "google/cloud/automl_v1/services/auto_ml/transports/__init__.py", - "google/cloud/automl_v1/services/auto_ml/transports/base.py", - "google/cloud/automl_v1/services/auto_ml/transports/grpc.py", - "google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py", - "google/cloud/automl_v1/services/prediction_service/__init__.py", - "google/cloud/automl_v1/services/prediction_service/async_client.py", - "google/cloud/automl_v1/services/prediction_service/client.py", - "google/cloud/automl_v1/services/prediction_service/transports/__init__.py", - "google/cloud/automl_v1/services/prediction_service/transports/base.py", - "google/cloud/automl_v1/services/prediction_service/transports/grpc.py", - "google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py", - "google/cloud/automl_v1/types/__init__.py", - "google/cloud/automl_v1/types/annotation_payload.py", - "google/cloud/automl_v1/types/annotation_spec.py", - "google/cloud/automl_v1/types/classification.py", - "google/cloud/automl_v1/types/data_items.py", - "google/cloud/automl_v1/types/dataset.py", - "google/cloud/automl_v1/types/detection.py", - "google/cloud/automl_v1/types/geometry.py", - "google/cloud/automl_v1/types/image.py", - "google/cloud/automl_v1/types/io.py", - "google/cloud/automl_v1/types/model.py", - "google/cloud/automl_v1/types/model_evaluation.py", - "google/cloud/automl_v1/types/operations.py", - "google/cloud/automl_v1/types/prediction_service.py", - "google/cloud/automl_v1/types/service.py", - "google/cloud/automl_v1/types/text.py", - "google/cloud/automl_v1/types/text_extraction.py", - "google/cloud/automl_v1/types/text_segment.py", - "google/cloud/automl_v1/types/text_sentiment.py", - "google/cloud/automl_v1/types/translation.py", - "google/cloud/automl_v1beta1/__init__.py", - "google/cloud/automl_v1beta1/proto/annotation_payload.proto", - "google/cloud/automl_v1beta1/proto/annotation_spec.proto", - "google/cloud/automl_v1beta1/proto/classification.proto", - "google/cloud/automl_v1beta1/proto/column_spec.proto", - "google/cloud/automl_v1beta1/proto/data_items.proto", - "google/cloud/automl_v1beta1/proto/data_stats.proto", - "google/cloud/automl_v1beta1/proto/data_types.proto", - "google/cloud/automl_v1beta1/proto/dataset.proto", - "google/cloud/automl_v1beta1/proto/detection.proto", - "google/cloud/automl_v1beta1/proto/geometry.proto", - "google/cloud/automl_v1beta1/proto/image.proto", - "google/cloud/automl_v1beta1/proto/io.proto", - "google/cloud/automl_v1beta1/proto/model.proto", - "google/cloud/automl_v1beta1/proto/model_evaluation.proto", - "google/cloud/automl_v1beta1/proto/operations.proto", - "google/cloud/automl_v1beta1/proto/prediction_service.proto", - "google/cloud/automl_v1beta1/proto/ranges.proto", - "google/cloud/automl_v1beta1/proto/regression.proto", - "google/cloud/automl_v1beta1/proto/service.proto", - "google/cloud/automl_v1beta1/proto/table_spec.proto", - "google/cloud/automl_v1beta1/proto/tables.proto", - "google/cloud/automl_v1beta1/proto/temporal.proto", - "google/cloud/automl_v1beta1/proto/text.proto", - "google/cloud/automl_v1beta1/proto/text_extraction.proto", - "google/cloud/automl_v1beta1/proto/text_segment.proto", - "google/cloud/automl_v1beta1/proto/text_sentiment.proto", - "google/cloud/automl_v1beta1/proto/translation.proto", - "google/cloud/automl_v1beta1/proto/video.proto", - "google/cloud/automl_v1beta1/py.typed", - "google/cloud/automl_v1beta1/services/__init__.py", - "google/cloud/automl_v1beta1/services/auto_ml/__init__.py", - "google/cloud/automl_v1beta1/services/auto_ml/async_client.py", - "google/cloud/automl_v1beta1/services/auto_ml/client.py", - "google/cloud/automl_v1beta1/services/auto_ml/pagers.py", - "google/cloud/automl_v1beta1/services/auto_ml/transports/__init__.py", - "google/cloud/automl_v1beta1/services/auto_ml/transports/base.py", - "google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py", - "google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py", - "google/cloud/automl_v1beta1/services/prediction_service/__init__.py", - "google/cloud/automl_v1beta1/services/prediction_service/async_client.py", - "google/cloud/automl_v1beta1/services/prediction_service/client.py", - "google/cloud/automl_v1beta1/services/prediction_service/transports/__init__.py", - "google/cloud/automl_v1beta1/services/prediction_service/transports/base.py", - "google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py", - "google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py", - "google/cloud/automl_v1beta1/types/__init__.py", - "google/cloud/automl_v1beta1/types/annotation_payload.py", - "google/cloud/automl_v1beta1/types/annotation_spec.py", - "google/cloud/automl_v1beta1/types/classification.py", - "google/cloud/automl_v1beta1/types/column_spec.py", - "google/cloud/automl_v1beta1/types/data_items.py", - "google/cloud/automl_v1beta1/types/data_stats.py", - "google/cloud/automl_v1beta1/types/data_types.py", - "google/cloud/automl_v1beta1/types/dataset.py", - "google/cloud/automl_v1beta1/types/detection.py", - "google/cloud/automl_v1beta1/types/geometry.py", - "google/cloud/automl_v1beta1/types/image.py", - "google/cloud/automl_v1beta1/types/io.py", - "google/cloud/automl_v1beta1/types/model.py", - "google/cloud/automl_v1beta1/types/model_evaluation.py", - "google/cloud/automl_v1beta1/types/operations.py", - "google/cloud/automl_v1beta1/types/prediction_service.py", - "google/cloud/automl_v1beta1/types/ranges.py", - "google/cloud/automl_v1beta1/types/regression.py", - "google/cloud/automl_v1beta1/types/service.py", - "google/cloud/automl_v1beta1/types/table_spec.py", - "google/cloud/automl_v1beta1/types/tables.py", - "google/cloud/automl_v1beta1/types/temporal.py", - "google/cloud/automl_v1beta1/types/text.py", - "google/cloud/automl_v1beta1/types/text_extraction.py", - "google/cloud/automl_v1beta1/types/text_segment.py", - "google/cloud/automl_v1beta1/types/text_sentiment.py", - "google/cloud/automl_v1beta1/types/translation.py", - "google/cloud/automl_v1beta1/types/video.py", - "mypy.ini", - "noxfile.py", - "renovate.json", - "samples/AUTHORING_GUIDE.md", - "samples/CONTRIBUTING.md", - "samples/beta/noxfile.py", - "samples/snippets/noxfile.py", - "samples/tables/noxfile.py", - "scripts/decrypt-secrets.sh", - "scripts/fixup_automl_v1_keywords.py", - "scripts/fixup_automl_v1beta1_keywords.py", - "scripts/readme-gen/readme_gen.py", - "scripts/readme-gen/templates/README.tmpl.rst", - "scripts/readme-gen/templates/auth.tmpl.rst", - "scripts/readme-gen/templates/auth_api_key.tmpl.rst", - "scripts/readme-gen/templates/install_deps.tmpl.rst", - "scripts/readme-gen/templates/install_portaudio.tmpl.rst", - "setup.cfg", - "testing/.gitignore", - "tests/unit/gapic/automl_v1/__init__.py", - "tests/unit/gapic/automl_v1/test_auto_ml.py", - "tests/unit/gapic/automl_v1/test_prediction_service.py", - "tests/unit/gapic/automl_v1beta1/__init__.py", - "tests/unit/gapic/automl_v1beta1/test_auto_ml.py", - "tests/unit/gapic/automl_v1beta1/test_prediction_service.py" ] } \ No newline at end of file diff --git a/tests/unit/gapic/automl_v1/test_auto_ml.py b/tests/unit/gapic/automl_v1/test_auto_ml.py index a567c98f..42ad394e 100644 --- a/tests/unit/gapic/automl_v1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1/test_auto_ml.py @@ -158,14 +158,15 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -174,14 +175,15 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -190,171 +192,95 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,use_client_cert_env", - [ - (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "true"), - ( - AutoMlAsyncClient, - transports.AutoMlGrpcAsyncIOTransport, - "grpc_asyncio", - "true", - ), - (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "false"), - ( - AutoMlAsyncClient, - transports.AutoMlGrpcAsyncIOTransport, - "grpc_asyncio", - "false", - ), - ], -) -@mock.patch.object( - AutoMlClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlClient) -) -@mock.patch.object( - AutoMlAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlAsyncClient) -) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_auto_ml_client_mtls_env_auto( - client_class, transport_class, transport_name, use_client_cert_env -): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=client_cert_source_callback, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and default_client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): patched.return_value = None - client = client_class(client_options=options) - - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT - + client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=expected_host, + host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", but client_cert_source and default_client_cert_source are None. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -377,7 +303,8 @@ def test_auto_ml_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -403,7 +330,8 @@ def test_auto_ml_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -420,7 +348,8 @@ def test_auto_ml_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -1109,8 +1038,8 @@ def test_list_datasets_pages(): RuntimeError, ) pages = list(client.list_datasets(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -1174,10 +1103,10 @@ async def test_list_datasets_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_datasets(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_datasets(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_update_dataset( @@ -2933,8 +2862,8 @@ def test_list_models_pages(): RuntimeError, ) pages = list(client.list_models(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -2990,10 +2919,10 @@ async def test_list_models_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_models(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_models(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelRequest): @@ -4530,8 +4459,8 @@ def test_list_model_evaluations_pages(): RuntimeError, ) pages = list(client.list_model_evaluations(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -4615,10 +4544,10 @@ async def test_list_model_evaluations_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_model_evaluations(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_model_evaluations(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_credentials_transport_error(): @@ -4675,18 +4604,6 @@ def test_transport_get_channel(): assert channel -@pytest.mark.parametrize( - "transport_class", - [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4763,17 +4680,6 @@ def test_auto_ml_base_transport_with_credentials_file(): ) -def test_auto_ml_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(auth, "default") as adc, mock.patch( - "google.cloud.automl_v1.services.auto_ml.transports.AutoMlTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) - transport = transports.AutoMlTransport() - adc.assert_called_once() - - def test_auto_ml_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -4822,102 +4728,179 @@ def test_auto_ml_host_with_port(): def test_auto_ml_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called def test_auto_ml_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_auto_ml_grpc_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.AutoMlGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.AutoMlGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_auto_ml_transport_channel_mtls_with_client_cert_source(transport_class): - with mock.patch( - "grpc.ssl_channel_credentials", autospec=True - ) as grpc_ssl_channel_cred: - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_auto_ml_grpc_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.AutoMlGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_auto_ml_transport_channel_mtls_with_adc(transport_class): +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + mock_cred = mock.Mock() + transport = transports.AutoMlGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_auto_ml_grpc_lro_client(): @@ -4946,53 +4929,53 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_dataset_path(): +def test_model_path(): project = "squid" location = "clam" - dataset = "whelk" + model = "whelk" - expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( - project=project, location=location, dataset=dataset, + expected = "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, ) - actual = AutoMlClient.dataset_path(project, location, dataset) + actual = AutoMlClient.model_path(project, location, model) assert expected == actual -def test_parse_dataset_path(): +def test_parse_model_path(): expected = { "project": "octopus", "location": "oyster", - "dataset": "nudibranch", + "model": "nudibranch", } - path = AutoMlClient.dataset_path(**expected) + path = AutoMlClient.model_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_dataset_path(path) + actual = AutoMlClient.parse_model_path(path) assert expected == actual -def test_model_path(): +def test_dataset_path(): project = "squid" location = "clam" - model = "whelk" + dataset = "whelk" - expected = "projects/{project}/locations/{location}/models/{model}".format( - project=project, location=location, model=model, + expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( + project=project, location=location, dataset=dataset, ) - actual = AutoMlClient.model_path(project, location, model) + actual = AutoMlClient.dataset_path(project, location, dataset) assert expected == actual -def test_parse_model_path(): +def test_parse_dataset_path(): expected = { "project": "octopus", "location": "oyster", - "model": "nudibranch", + "dataset": "nudibranch", } - path = AutoMlClient.model_path(**expected) + path = AutoMlClient.dataset_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_model_path(path) + actual = AutoMlClient.parse_dataset_path(path) assert expected == actual diff --git a/tests/unit/gapic/automl_v1/test_prediction_service.py b/tests/unit/gapic/automl_v1/test_prediction_service.py index 37efdce5..a0087eae 100644 --- a/tests/unit/gapic/automl_v1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1/test_prediction_service.py @@ -167,14 +167,15 @@ def test_prediction_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -183,14 +184,15 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -199,185 +201,95 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,use_client_cert_env", - [ - ( - PredictionServiceClient, - transports.PredictionServiceGrpcTransport, - "grpc", - "true", - ), - ( - PredictionServiceAsyncClient, - transports.PredictionServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "true", - ), - ( - PredictionServiceClient, - transports.PredictionServiceGrpcTransport, - "grpc", - "false", - ), - ( - PredictionServiceAsyncClient, - transports.PredictionServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "false", - ), - ], -) -@mock.patch.object( - PredictionServiceClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(PredictionServiceClient), -) -@mock.patch.object( - PredictionServiceAsyncClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(PredictionServiceAsyncClient), -) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_prediction_service_client_mtls_env_auto( - client_class, transport_class, transport_name, use_client_cert_env -): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=client_cert_source_callback, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and default_client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): patched.return_value = None - client = client_class(client_options=options) - - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT - + client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=expected_host, + host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", but client_cert_source and default_client_cert_source are None. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -404,7 +316,8 @@ def test_prediction_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -434,7 +347,8 @@ def test_prediction_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -453,7 +367,8 @@ def test_prediction_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -989,21 +904,6 @@ def test_transport_get_channel(): assert channel -@pytest.mark.parametrize( - "transport_class", - [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -1064,17 +964,6 @@ def test_prediction_service_base_transport_with_credentials_file(): ) -def test_prediction_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(auth, "default") as adc, mock.patch( - "google.cloud.automl_v1.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) - transport = transports.PredictionServiceTransport() - adc.assert_called_once() - - def test_prediction_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -1123,110 +1012,179 @@ def test_prediction_service_host_with_port(): def test_prediction_service_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called def test_prediction_service_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_prediction_service_grpc_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.PredictionServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.PredictionServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, - ], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_prediction_service_transport_channel_mtls_with_client_cert_source( - transport_class, +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_prediction_service_grpc_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint ): - with mock.patch( - "grpc.ssl_channel_credentials", autospec=True - ) as grpc_ssl_channel_cred: - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.PredictionServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, - ], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_prediction_service_transport_channel_mtls_with_adc(transport_class): +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + mock_cred = mock.Mock() + transport = transports.PredictionServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_prediction_service_grpc_lro_client(): diff --git a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py index ebb97c59..2464c824 100644 --- a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py @@ -168,14 +168,15 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -184,14 +185,15 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -200,171 +202,95 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,use_client_cert_env", - [ - (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "true"), - ( - AutoMlAsyncClient, - transports.AutoMlGrpcAsyncIOTransport, - "grpc_asyncio", - "true", - ), - (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "false"), - ( - AutoMlAsyncClient, - transports.AutoMlGrpcAsyncIOTransport, - "grpc_asyncio", - "false", - ), - ], -) -@mock.patch.object( - AutoMlClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlClient) -) -@mock.patch.object( - AutoMlAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlAsyncClient) -) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_auto_ml_client_mtls_env_auto( - client_class, transport_class, transport_name, use_client_cert_env -): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=client_cert_source_callback, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and default_client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): patched.return_value = None - client = client_class(client_options=options) - - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT - + client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=expected_host, + host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", but client_cert_source and default_client_cert_source are None. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -387,7 +313,8 @@ def test_auto_ml_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -413,7 +340,8 @@ def test_auto_ml_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -430,7 +358,8 @@ def test_auto_ml_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -1150,8 +1079,8 @@ def test_list_datasets_pages(): RuntimeError, ) pages = list(client.list_datasets(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -1215,10 +1144,10 @@ async def test_list_datasets_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_datasets(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_datasets(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_update_dataset( @@ -2782,8 +2711,8 @@ def test_list_table_specs_pages(): RuntimeError, ) pages = list(client.list_table_specs(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -2855,10 +2784,10 @@ async def test_list_table_specs_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_table_specs(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_table_specs(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_update_table_spec( @@ -3565,8 +3494,8 @@ def test_list_column_specs_pages(): RuntimeError, ) pages = list(client.list_column_specs(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -3638,10 +3567,10 @@ async def test_list_column_specs_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_column_specs(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_column_specs(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_update_column_spec( @@ -4526,8 +4455,8 @@ def test_list_models_pages(): RuntimeError, ) pages = list(client.list_models(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -4583,10 +4512,10 @@ async def test_list_models_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_models(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_models(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelRequest): @@ -6084,8 +6013,8 @@ def test_list_model_evaluations_pages(): RuntimeError, ) pages = list(client.list_model_evaluations(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -6169,10 +6098,10 @@ async def test_list_model_evaluations_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_model_evaluations(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_model_evaluations(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_credentials_transport_error(): @@ -6229,18 +6158,6 @@ def test_transport_get_channel(): assert channel -@pytest.mark.parametrize( - "transport_class", - [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -6323,17 +6240,6 @@ def test_auto_ml_base_transport_with_credentials_file(): ) -def test_auto_ml_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(auth, "default") as adc, mock.patch( - "google.cloud.automl_v1beta1.services.auto_ml.transports.AutoMlTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) - transport = transports.AutoMlTransport() - adc.assert_called_once() - - def test_auto_ml_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -6382,102 +6288,179 @@ def test_auto_ml_host_with_port(): def test_auto_ml_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called def test_auto_ml_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_auto_ml_grpc_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.AutoMlGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.AutoMlGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_auto_ml_transport_channel_mtls_with_client_cert_source(transport_class): - with mock.patch( - "grpc.ssl_channel_credentials", autospec=True - ) as grpc_ssl_channel_cred: - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_auto_ml_grpc_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.AutoMlGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_auto_ml_transport_channel_mtls_with_adc(transport_class): +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + mock_cred = mock.Mock() + transport = transports.AutoMlGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_auto_ml_grpc_lro_client(): @@ -6506,41 +6489,6 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_column_spec_path(): - project = "squid" - location = "clam" - dataset = "whelk" - table_spec = "octopus" - column_spec = "oyster" - - expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}".format( - project=project, - location=location, - dataset=dataset, - table_spec=table_spec, - column_spec=column_spec, - ) - actual = AutoMlClient.column_spec_path( - project, location, dataset, table_spec, column_spec - ) - assert expected == actual - - -def test_parse_column_spec_path(): - expected = { - "project": "nudibranch", - "location": "cuttlefish", - "dataset": "mussel", - "table_spec": "winkle", - "column_spec": "nautilus", - } - path = AutoMlClient.column_spec_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_column_spec_path(path) - assert expected == actual - - def test_dataset_path(): project = "squid" location = "clam" @@ -6591,6 +6539,41 @@ def test_parse_model_path(): assert expected == actual +def test_column_spec_path(): + project = "squid" + location = "clam" + dataset = "whelk" + table_spec = "octopus" + column_spec = "oyster" + + expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}".format( + project=project, + location=location, + dataset=dataset, + table_spec=table_spec, + column_spec=column_spec, + ) + actual = AutoMlClient.column_spec_path( + project, location, dataset, table_spec, column_spec + ) + assert expected == actual + + +def test_parse_column_spec_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "dataset": "mussel", + "table_spec": "winkle", + "column_spec": "nautilus", + } + path = AutoMlClient.column_spec_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_column_spec_path(path) + assert expected == actual + + def test_table_spec_path(): project = "squid" location = "clam" diff --git a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py index 4d9e45a9..c21f17b9 100644 --- a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py @@ -170,14 +170,15 @@ def test_prediction_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -186,14 +187,15 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -202,185 +204,95 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,use_client_cert_env", - [ - ( - PredictionServiceClient, - transports.PredictionServiceGrpcTransport, - "grpc", - "true", - ), - ( - PredictionServiceAsyncClient, - transports.PredictionServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "true", - ), - ( - PredictionServiceClient, - transports.PredictionServiceGrpcTransport, - "grpc", - "false", - ), - ( - PredictionServiceAsyncClient, - transports.PredictionServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "false", - ), - ], -) -@mock.patch.object( - PredictionServiceClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(PredictionServiceClient), -) -@mock.patch.object( - PredictionServiceAsyncClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(PredictionServiceAsyncClient), -) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_prediction_service_client_mtls_env_auto( - client_class, transport_class, transport_name, use_client_cert_env -): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=client_cert_source_callback, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and default_client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): patched.return_value = None - client = client_class(client_options=options) - - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT - + client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=expected_host, + host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", but client_cert_source and default_client_cert_source are None. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -407,7 +319,8 @@ def test_prediction_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -437,7 +350,8 @@ def test_prediction_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -456,7 +370,8 @@ def test_prediction_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -992,21 +907,6 @@ def test_transport_get_channel(): assert channel -@pytest.mark.parametrize( - "transport_class", - [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -1067,17 +967,6 @@ def test_prediction_service_base_transport_with_credentials_file(): ) -def test_prediction_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(auth, "default") as adc, mock.patch( - "google.cloud.automl_v1beta1.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) - transport = transports.PredictionServiceTransport() - adc.assert_called_once() - - def test_prediction_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -1126,110 +1015,179 @@ def test_prediction_service_host_with_port(): def test_prediction_service_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called def test_prediction_service_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_prediction_service_grpc_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.PredictionServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.PredictionServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, - ], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_prediction_service_transport_channel_mtls_with_client_cert_source( - transport_class, +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_prediction_service_grpc_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint ): - with mock.patch( - "grpc.ssl_channel_credentials", autospec=True - ) as grpc_ssl_channel_cred: - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.PredictionServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, - ], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_prediction_service_transport_channel_mtls_with_adc(transport_class): +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + mock_cred = mock.Mock() + transport = transports.PredictionServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_prediction_service_grpc_lro_client(): From 4696421e3e6228c0b803073ea3fc3373941c42a0 Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:55:12 -0700 Subject: [PATCH 09/25] Publish SLM logging proto for documentation PiperOrigin-RevId: 333125205 Source-Author: Google APIs Source-Date: Tue Sep 22 11:39:20 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: 4ede77543c77072a2ac9f78353de2de2f8c4c501 Source-Link: https://github.com/googleapis/googleapis/commit/4ede77543c77072a2ac9f78353de2de2f8c4c501 --- docs/automl_v1beta1/services.rst | 3 - google/cloud/automl_v1/__init__.py | 4 +- .../services/auto_ml/async_client.py | 24 +- .../automl_v1/services/auto_ml/client.py | 70 +- .../services/auto_ml/transports/base.py | 2 +- .../services/auto_ml/transports/grpc.py | 46 +- .../auto_ml/transports/grpc_asyncio.py | 51 +- .../prediction_service/async_client.py | 19 +- .../services/prediction_service/client.py | 70 +- .../prediction_service/transports/base.py | 2 +- .../prediction_service/transports/grpc.py | 46 +- .../transports/grpc_asyncio.py | 51 +- google/cloud/automl_v1beta1/__init__.py | 4 +- .../proto/annotation_payload.proto | 77 ++ .../proto/annotation_spec.proto | 48 + .../automl_v1beta1/proto/classification.proto | 216 ++++ .../automl_v1beta1/proto/column_spec.proto | 78 ++ .../automl_v1beta1/proto/data_items.proto | 221 ++++ .../automl_v1beta1/proto/data_stats.proto | 166 +++ .../automl_v1beta1/proto/data_types.proto | 105 ++ .../cloud/automl_v1beta1/proto/dataset.proto | 96 ++ .../automl_v1beta1/proto/detection.proto | 135 ++ .../cloud/automl_v1beta1/proto/geometry.proto | 46 + google/cloud/automl_v1beta1/proto/image.proto | 193 +++ google/cloud/automl_v1beta1/proto/io.proto | 1132 +++++++++++++++++ google/cloud/automl_v1beta1/proto/model.proto | 108 ++ .../proto/model_evaluation.proto | 116 ++ .../automl_v1beta1/proto/operations.proto | 189 +++ .../proto/prediction_service.proto | 268 ++++ .../cloud/automl_v1beta1/proto/ranges.proto | 35 + .../automl_v1beta1/proto/regression.proto | 44 + .../cloud/automl_v1beta1/proto/service.proto | 800 ++++++++++++ .../automl_v1beta1/proto/table_spec.proto | 78 ++ .../cloud/automl_v1beta1/proto/tables.proto | 292 +++++ .../cloud/automl_v1beta1/proto/temporal.proto | 37 + google/cloud/automl_v1beta1/proto/text.proto | 65 + .../proto/text_extraction.proto | 68 + .../automl_v1beta1/proto/text_segment.proto | 41 + .../automl_v1beta1/proto/text_sentiment.proto | 80 ++ .../automl_v1beta1/proto/translation.proto | 69 + google/cloud/automl_v1beta1/proto/video.proto | 48 + .../services/auto_ml/async_client.py | 28 +- .../automl_v1beta1/services/auto_ml/client.py | 70 +- .../services/auto_ml/transports/base.py | 2 +- .../services/auto_ml/transports/grpc.py | 46 +- .../auto_ml/transports/grpc_asyncio.py | 51 +- .../prediction_service/async_client.py | 19 +- .../services/prediction_service/client.py | 70 +- .../prediction_service/transports/base.py | 2 +- .../prediction_service/transports/grpc.py | 46 +- .../transports/grpc_asyncio.py | 51 +- noxfile.py | 34 - synth.metadata | 224 +++- tests/unit/gapic/automl_v1/test_auto_ml.py | 543 ++++---- .../automl_v1/test_prediction_service.py | 494 +++---- .../unit/gapic/automl_v1beta1/test_auto_ml.py | 601 ++++----- .../automl_v1beta1/test_prediction_service.py | 494 +++---- 57 files changed, 6720 insertions(+), 1298 deletions(-) create mode 100644 google/cloud/automl_v1beta1/proto/annotation_payload.proto create mode 100644 google/cloud/automl_v1beta1/proto/annotation_spec.proto create mode 100644 google/cloud/automl_v1beta1/proto/classification.proto create mode 100644 google/cloud/automl_v1beta1/proto/column_spec.proto create mode 100644 google/cloud/automl_v1beta1/proto/data_items.proto create mode 100644 google/cloud/automl_v1beta1/proto/data_stats.proto create mode 100644 google/cloud/automl_v1beta1/proto/data_types.proto create mode 100644 google/cloud/automl_v1beta1/proto/dataset.proto create mode 100644 google/cloud/automl_v1beta1/proto/detection.proto create mode 100644 google/cloud/automl_v1beta1/proto/geometry.proto create mode 100644 google/cloud/automl_v1beta1/proto/image.proto create mode 100644 google/cloud/automl_v1beta1/proto/io.proto create mode 100644 google/cloud/automl_v1beta1/proto/model.proto create mode 100644 google/cloud/automl_v1beta1/proto/model_evaluation.proto create mode 100644 google/cloud/automl_v1beta1/proto/operations.proto create mode 100644 google/cloud/automl_v1beta1/proto/prediction_service.proto create mode 100644 google/cloud/automl_v1beta1/proto/ranges.proto create mode 100644 google/cloud/automl_v1beta1/proto/regression.proto create mode 100644 google/cloud/automl_v1beta1/proto/service.proto create mode 100644 google/cloud/automl_v1beta1/proto/table_spec.proto create mode 100644 google/cloud/automl_v1beta1/proto/tables.proto create mode 100644 google/cloud/automl_v1beta1/proto/temporal.proto create mode 100644 google/cloud/automl_v1beta1/proto/text.proto create mode 100644 google/cloud/automl_v1beta1/proto/text_extraction.proto create mode 100644 google/cloud/automl_v1beta1/proto/text_segment.proto create mode 100644 google/cloud/automl_v1beta1/proto/text_sentiment.proto create mode 100644 google/cloud/automl_v1beta1/proto/translation.proto create mode 100644 google/cloud/automl_v1beta1/proto/video.proto diff --git a/docs/automl_v1beta1/services.rst b/docs/automl_v1beta1/services.rst index 787e8566..9fa5c54f 100644 --- a/docs/automl_v1beta1/services.rst +++ b/docs/automl_v1beta1/services.rst @@ -7,6 +7,3 @@ Services for Google Cloud Automl v1beta1 API .. automodule:: google.cloud.automl_v1beta1.services.prediction_service :members: :inherited-members: -.. automodule:: google.cloud.automl_v1beta1.services.tables - :members: - :inherited-members: diff --git a/google/cloud/automl_v1/__init__.py b/google/cloud/automl_v1/__init__.py index b5f76f81..6f22bb65 100644 --- a/google/cloud/automl_v1/__init__.py +++ b/google/cloud/automl_v1/__init__.py @@ -104,6 +104,7 @@ __all__ = ( "AnnotationPayload", "AnnotationSpec", + "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -164,7 +165,6 @@ "OutputConfig", "PredictRequest", "PredictResponse", - "PredictionServiceClient", "TextClassificationDatasetMetadata", "TextClassificationModelMetadata", "TextExtractionAnnotation", @@ -185,5 +185,5 @@ "UndeployModelRequest", "UpdateDatasetRequest", "UpdateModelRequest", - "AutoMlClient", + "PredictionServiceClient", ) diff --git a/google/cloud/automl_v1/services/auto_ml/async_client.py b/google/cloud/automl_v1/services/auto_ml/async_client.py index 2b7f9c5c..9dd21f72 100644 --- a/google/cloud/automl_v1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1/services/auto_ml/async_client.py @@ -79,9 +79,10 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT - model_path = staticmethod(AutoMlClient.model_path) - dataset_path = staticmethod(AutoMlClient.dataset_path) + parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) + model_path = staticmethod(AutoMlClient.model_path) + parse_model_path = staticmethod(AutoMlClient.parse_model_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file @@ -112,16 +113,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1/services/auto_ml/client.py b/google/cloud/automl_v1/services/auto_ml/client.py index e615ce00..6cace8ae 100644 --- a/google/cloud/automl_v1/services/auto_ml/client.py +++ b/google/cloud/automl_v1/services/auto_ml/client.py @@ -16,6 +16,7 @@ # from collections import OrderedDict +from distutils import util import os import re from typing import Callable, Dict, Sequence, Tuple, Type, Union @@ -27,6 +28,7 @@ from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore @@ -215,16 +217,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -240,25 +245,43 @@ def __init__( if client_options is None: client_options = ClientOptions.ClientOptions() - if client_options.api_endpoint is None: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + ssl_credentials = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + import grpc # type: ignore + + cert, key = client_options.client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + is_mtls = True + else: + creds = SslCredentials() + is_mtls = creds.is_mtls + ssl_credentials = creds.ssl_credentials if is_mtls else None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") if use_mtls_env == "never": - client_options.api_endpoint = self.DEFAULT_ENDPOINT + api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - has_client_cert_source = ( - client_options.client_cert_source is not None - or mtls.has_default_client_cert_source() - ) - client_options.api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT - if has_client_cert_source - else self.DEFAULT_ENDPOINT + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -282,10 +305,9 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=client_options.api_endpoint, + host=api_endpoint, scopes=client_options.scopes, - api_mtls_endpoint=client_options.api_endpoint, - client_cert_source=client_options.client_cert_source, + ssl_channel_credentials=ssl_credentials, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1/services/auto_ml/transports/base.py b/google/cloud/automl_v1/services/auto_ml/transports/base.py index 5e230105..b1e12781 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth +from google import auth # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py index 100f50f6..b957e5cd 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py @@ -15,6 +15,7 @@ # limitations under the License. # +import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -24,7 +25,6 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore - import grpc # type: ignore from google.cloud.automl_v1.types import annotation_spec @@ -78,6 +78,7 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -98,14 +99,16 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -128,6 +131,11 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -158,6 +166,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) self._stubs = {} # type: Dict[str, Callable] @@ -223,13 +248,6 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py b/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py index 39e15a79..0778c063 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py @@ -15,11 +15,13 @@ # limitations under the License. # +import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore +from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -120,6 +122,7 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -141,14 +144,16 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -171,12 +176,22 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -196,6 +211,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) # Run the base constructor. super().__init__( @@ -216,13 +248,6 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/prediction_service/async_client.py b/google/cloud/automl_v1/services/prediction_service/async_client.py index df141602..fe1d2226 100644 --- a/google/cloud/automl_v1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1/services/prediction_service/async_client.py @@ -82,16 +82,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1/services/prediction_service/client.py b/google/cloud/automl_v1/services/prediction_service/client.py index 2ccfd9fc..d557fd9b 100644 --- a/google/cloud/automl_v1/services/prediction_service/client.py +++ b/google/cloud/automl_v1/services/prediction_service/client.py @@ -16,6 +16,7 @@ # from collections import OrderedDict +from distutils import util import os import re from typing import Callable, Dict, Sequence, Tuple, Type, Union @@ -27,6 +28,7 @@ from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore @@ -161,16 +163,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -186,25 +191,43 @@ def __init__( if client_options is None: client_options = ClientOptions.ClientOptions() - if client_options.api_endpoint is None: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + ssl_credentials = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + import grpc # type: ignore + + cert, key = client_options.client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + is_mtls = True + else: + creds = SslCredentials() + is_mtls = creds.is_mtls + ssl_credentials = creds.ssl_credentials if is_mtls else None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") if use_mtls_env == "never": - client_options.api_endpoint = self.DEFAULT_ENDPOINT + api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - has_client_cert_source = ( - client_options.client_cert_source is not None - or mtls.has_default_client_cert_source() - ) - client_options.api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT - if has_client_cert_source - else self.DEFAULT_ENDPOINT + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -228,10 +251,9 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=client_options.api_endpoint, + host=api_endpoint, scopes=client_options.scopes, - api_mtls_endpoint=client_options.api_endpoint, - client_cert_source=client_options.client_cert_source, + ssl_channel_credentials=ssl_credentials, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1/services/prediction_service/transports/base.py b/google/cloud/automl_v1/services/prediction_service/transports/base.py index 349d8793..f019a8dc 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/base.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth +from google import auth # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py index e4508add..9a2c8e9b 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py @@ -15,6 +15,7 @@ # limitations under the License. # +import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -24,7 +25,6 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore - import grpc # type: ignore from google.cloud.automl_v1.types import prediction_service @@ -61,6 +61,7 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -81,14 +82,16 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -111,6 +114,11 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -141,6 +149,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) self._stubs = {} # type: Dict[str, Callable] @@ -206,13 +231,6 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py b/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py index f92ad264..eddcb6ab 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py @@ -15,11 +15,13 @@ # limitations under the License. # +import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore +from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -103,6 +105,7 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -124,14 +127,16 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -154,12 +159,22 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -179,6 +194,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) # Run the base constructor. super().__init__( @@ -199,13 +231,6 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 904a45aa..30db2703 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -17,8 +17,8 @@ from .services.auto_ml import AutoMlClient from .services.prediction_service import PredictionServiceClient -from .services.tables.gcs_client import GcsClient -from .services.tables.tables_client import TablesClient +from .tables.gcs_client import GcsClient +from .tables.tables_client import TablesClient from .types.annotation_payload import AnnotationPayload from .types.annotation_spec import AnnotationSpec from .types.classification import ClassificationAnnotation diff --git a/google/cloud/automl_v1beta1/proto/annotation_payload.proto b/google/cloud/automl_v1beta1/proto/annotation_payload.proto new file mode 100644 index 00000000..f62bb269 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/annotation_payload.proto @@ -0,0 +1,77 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/cloud/automl/v1beta1/detection.proto"; +import "google/cloud/automl/v1beta1/tables.proto"; +import "google/cloud/automl/v1beta1/text_extraction.proto"; +import "google/cloud/automl/v1beta1/text_sentiment.proto"; +import "google/cloud/automl/v1beta1/translation.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Contains annotation information that is relevant to AutoML. +message AnnotationPayload { + // Output only . Additional information about the annotation + // specific to the AutoML domain. + oneof detail { + // Annotation details for translation. + TranslationAnnotation translation = 2; + + // Annotation details for content or image classification. + ClassificationAnnotation classification = 3; + + // Annotation details for image object detection. + ImageObjectDetectionAnnotation image_object_detection = 4; + + // Annotation details for video classification. + // Returned for Video Classification predictions. + VideoClassificationAnnotation video_classification = 9; + + // Annotation details for video object tracking. + VideoObjectTrackingAnnotation video_object_tracking = 8; + + // Annotation details for text extraction. + TextExtractionAnnotation text_extraction = 6; + + // Annotation details for text sentiment. + TextSentimentAnnotation text_sentiment = 7; + + // Annotation details for Tables. + TablesAnnotation tables = 10; + } + + // Output only . The resource ID of the annotation spec that + // this annotation pertains to. The annotation spec comes from either an + // ancestor dataset, or the dataset that was used to train the model in use. + string annotation_spec_id = 1; + + // Output only. The value of + // [display_name][google.cloud.automl.v1beta1.AnnotationSpec.display_name] + // when the model was trained. Because this field returns a value at model + // training time, for different models trained using the same dataset, the + // returned value could be different as model owner could update the + // `display_name` between any two model training. + string display_name = 5; +} diff --git a/google/cloud/automl_v1beta1/proto/annotation_spec.proto b/google/cloud/automl_v1beta1/proto/annotation_spec.proto new file mode 100644 index 00000000..d9df07ee --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/annotation_spec.proto @@ -0,0 +1,48 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A definition of an annotation spec. +message AnnotationSpec { + option (google.api.resource) = { + type: "automl.googleapis.com/AnnotationSpec" + pattern: "projects/{project}/locations/{location}/datasets/{dataset}/annotationSpecs/{annotation_spec}" + }; + + // Output only. Resource name of the annotation spec. + // Form: + // + // 'projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/annotationSpecs/{annotation_spec_id}' + string name = 1; + + // Required. The name of the annotation spec to show in the interface. The name can be + // up to 32 characters long and must match the regexp `[a-zA-Z0-9_]+`. + string display_name = 2; + + // Output only. The number of examples in the parent dataset + // labeled by the annotation spec. + int32 example_count = 9; +} diff --git a/google/cloud/automl_v1beta1/proto/classification.proto b/google/cloud/automl_v1beta1/proto/classification.proto new file mode 100644 index 00000000..0594d01e --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/classification.proto @@ -0,0 +1,216 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/temporal.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_outer_classname = "ClassificationProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Type of the classification problem. +enum ClassificationType { + // An un-set value of this enum. + CLASSIFICATION_TYPE_UNSPECIFIED = 0; + + // At most one label is allowed per example. + MULTICLASS = 1; + + // Multiple labels are allowed for one example. + MULTILABEL = 2; +} + +// Contains annotation details specific to classification. +message ClassificationAnnotation { + // Output only. A confidence estimate between 0.0 and 1.0. A higher value + // means greater confidence that the annotation is positive. If a user + // approves an annotation as negative or positive, the score value remains + // unchanged. If a user creates an annotation, the score is 0 for negative or + // 1 for positive. + float score = 1; +} + +// Contains annotation details specific to video classification. +message VideoClassificationAnnotation { + // Output only. Expresses the type of video classification. Possible values: + // + // * `segment` - Classification done on a specified by user + // time segment of a video. AnnotationSpec is answered to be present + // in that time segment, if it is present in any part of it. The video + // ML model evaluations are done only for this type of classification. + // + // * `shot`- Shot-level classification. + // AutoML Video Intelligence determines the boundaries + // for each camera shot in the entire segment of the video that user + // specified in the request configuration. AutoML Video Intelligence + // then returns labels and their confidence scores for each detected + // shot, along with the start and end time of the shot. + // WARNING: Model evaluation is not done for this classification type, + // the quality of it depends on training data, but there are no + // metrics provided to describe that quality. + // + // * `1s_interval` - AutoML Video Intelligence returns labels and their + // confidence scores for each second of the entire segment of the video + // that user specified in the request configuration. + // WARNING: Model evaluation is not done for this classification type, + // the quality of it depends on training data, but there are no + // metrics provided to describe that quality. + string type = 1; + + // Output only . The classification details of this annotation. + ClassificationAnnotation classification_annotation = 2; + + // Output only . The time segment of the video to which the + // annotation applies. + TimeSegment time_segment = 3; +} + +// Model evaluation metrics for classification problems. +// Note: For Video Classification this metrics only describe quality of the +// Video Classification predictions of "segment_classification" type. +message ClassificationEvaluationMetrics { + // Metrics for a single confidence threshold. + message ConfidenceMetricsEntry { + // Output only. Metrics are computed with an assumption that the model + // never returns predictions with score lower than this value. + float confidence_threshold = 1; + + // Output only. Metrics are computed with an assumption that the model + // always returns at most this many predictions (ordered by their score, + // descendingly), but they all still need to meet the confidence_threshold. + int32 position_threshold = 14; + + // Output only. Recall (True Positive Rate) for the given confidence + // threshold. + float recall = 2; + + // Output only. Precision for the given confidence threshold. + float precision = 3; + + // Output only. False Positive Rate for the given confidence threshold. + float false_positive_rate = 8; + + // Output only. The harmonic mean of recall and precision. + float f1_score = 4; + + // Output only. The Recall (True Positive Rate) when only considering the + // label that has the highest prediction score and not below the confidence + // threshold for each example. + float recall_at1 = 5; + + // Output only. The precision when only considering the label that has the + // highest prediction score and not below the confidence threshold for each + // example. + float precision_at1 = 6; + + // Output only. The False Positive Rate when only considering the label that + // has the highest prediction score and not below the confidence threshold + // for each example. + float false_positive_rate_at1 = 9; + + // Output only. The harmonic mean of [recall_at1][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfidenceMetricsEntry.recall_at1] and [precision_at1][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfidenceMetricsEntry.precision_at1]. + float f1_score_at1 = 7; + + // Output only. The number of model created labels that match a ground truth + // label. + int64 true_positive_count = 10; + + // Output only. The number of model created labels that do not match a + // ground truth label. + int64 false_positive_count = 11; + + // Output only. The number of ground truth labels that are not matched + // by a model created label. + int64 false_negative_count = 12; + + // Output only. The number of labels that were not created by the model, + // but if they would, they would not match a ground truth label. + int64 true_negative_count = 13; + } + + // Confusion matrix of the model running the classification. + message ConfusionMatrix { + // Output only. A row in the confusion matrix. + message Row { + // Output only. Value of the specific cell in the confusion matrix. + // The number of values each row has (i.e. the length of the row) is equal + // to the length of the `annotation_spec_id` field or, if that one is not + // populated, length of the [display_name][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfusionMatrix.display_name] field. + repeated int32 example_count = 1; + } + + // Output only. IDs of the annotation specs used in the confusion matrix. + // For Tables CLASSIFICATION + // + // [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] + // only list of [annotation_spec_display_name-s][] is populated. + repeated string annotation_spec_id = 1; + + // Output only. Display name of the annotation specs used in the confusion + // matrix, as they were at the moment of the evaluation. For Tables + // CLASSIFICATION + // + // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type], + // distinct values of the target column at the moment of the model + // evaluation are populated here. + repeated string display_name = 3; + + // Output only. Rows in the confusion matrix. The number of rows is equal to + // the size of `annotation_spec_id`. + // `row[i].example_count[j]` is the number of examples that have ground + // truth of the `annotation_spec_id[i]` and are predicted as + // `annotation_spec_id[j]` by the model being evaluated. + repeated Row row = 2; + } + + // Output only. The Area Under Precision-Recall Curve metric. Micro-averaged + // for the overall evaluation. + float au_prc = 1; + + // Output only. The Area Under Precision-Recall Curve metric based on priors. + // Micro-averaged for the overall evaluation. + // Deprecated. + float base_au_prc = 2 [deprecated = true]; + + // Output only. The Area Under Receiver Operating Characteristic curve metric. + // Micro-averaged for the overall evaluation. + float au_roc = 6; + + // Output only. The Log Loss metric. + float log_loss = 7; + + // Output only. Metrics for each confidence_threshold in + // 0.00,0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 and + // position_threshold = INT32_MAX_VALUE. + // ROC and precision-recall curves, and other aggregated metrics are derived + // from them. The confidence metrics entries may also be supplied for + // additional values of position_threshold, but from these no aggregated + // metrics are computed. + repeated ConfidenceMetricsEntry confidence_metrics_entry = 3; + + // Output only. Confusion matrix of the evaluation. + // Only set for MULTICLASS classification problems where number + // of labels is no more than 10. + // Only set for model level evaluation, not for evaluation per label. + ConfusionMatrix confusion_matrix = 4; + + // Output only. The annotation spec ids used for this evaluation. + repeated string annotation_spec_id = 5; +} diff --git a/google/cloud/automl_v1beta1/proto/column_spec.proto b/google/cloud/automl_v1beta1/proto/column_spec.proto new file mode 100644 index 00000000..03389b8a --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/column_spec.proto @@ -0,0 +1,78 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/data_stats.proto"; +import "google/cloud/automl/v1beta1/data_types.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A representation of a column in a relational table. When listing them, column specs are returned in the same order in which they were +// given on import . +// Used by: +// * Tables +message ColumnSpec { + option (google.api.resource) = { + type: "automl.googleapis.com/ColumnSpec" + pattern: "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}" + }; + + // Identifies the table's column, and its correlation with the column this + // ColumnSpec describes. + message CorrelatedColumn { + // The column_spec_id of the correlated column, which belongs to the same + // table as the in-context column. + string column_spec_id = 1; + + // Correlation between this and the in-context column. + CorrelationStats correlation_stats = 2; + } + + // Output only. The resource name of the column specs. + // Form: + // + // `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/tableSpecs/{table_spec_id}/columnSpecs/{column_spec_id}` + string name = 1; + + // The data type of elements stored in the column. + DataType data_type = 2; + + // Output only. The name of the column to show in the interface. The name can + // be up to 100 characters long and can consist only of ASCII Latin letters + // A-Z and a-z, ASCII digits 0-9, underscores(_), and forward slashes(/), and + // must start with a letter or a digit. + string display_name = 3; + + // Output only. Stats of the series of values in the column. + // This field may be stale, see the ancestor's + // Dataset.tables_dataset_metadata.stats_update_time field + // for the timestamp at which these stats were last updated. + DataStats data_stats = 4; + + // Deprecated. + repeated CorrelatedColumn top_correlated_columns = 5; + + // Used to perform consistent read-modify-write updates. If not set, a blind + // "overwrite" update happens. + string etag = 6; +} diff --git a/google/cloud/automl_v1beta1/proto/data_items.proto b/google/cloud/automl_v1beta1/proto/data_items.proto new file mode 100644 index 00000000..9b9187ad --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/data_items.proto @@ -0,0 +1,221 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/geometry.proto"; +import "google/cloud/automl/v1beta1/io.proto"; +import "google/cloud/automl/v1beta1/temporal.proto"; +import "google/cloud/automl/v1beta1/text_segment.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/struct.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A representation of an image. +// Only images up to 30MB in size are supported. +message Image { + // Input only. The data representing the image. + // For Predict calls [image_bytes][google.cloud.automl.v1beta1.Image.image_bytes] must be set, as other options are not + // currently supported by prediction API. You can read the contents of an + // uploaded image by using the [content_uri][google.cloud.automl.v1beta1.Image.content_uri] field. + oneof data { + // Image content represented as a stream of bytes. + // Note: As with all `bytes` fields, protobuffers use a pure binary + // representation, whereas JSON representations use base64. + bytes image_bytes = 1; + + // An input config specifying the content of the image. + InputConfig input_config = 6; + } + + // Output only. HTTP URI to the thumbnail image. + string thumbnail_uri = 4; +} + +// A representation of a text snippet. +message TextSnippet { + // Required. The content of the text snippet as a string. Up to 250000 + // characters long. + string content = 1; + + // Optional. The format of [content][google.cloud.automl.v1beta1.TextSnippet.content]. Currently the only two allowed + // values are "text/html" and "text/plain". If left blank, the format is + // automatically determined from the type of the uploaded [content][google.cloud.automl.v1beta1.TextSnippet.content]. + string mime_type = 2; + + // Output only. HTTP URI where you can download the content. + string content_uri = 4; +} + +// Message that describes dimension of a document. +message DocumentDimensions { + // Unit of the document dimension. + enum DocumentDimensionUnit { + // Should not be used. + DOCUMENT_DIMENSION_UNIT_UNSPECIFIED = 0; + + // Document dimension is measured in inches. + INCH = 1; + + // Document dimension is measured in centimeters. + CENTIMETER = 2; + + // Document dimension is measured in points. 72 points = 1 inch. + POINT = 3; + } + + // Unit of the dimension. + DocumentDimensionUnit unit = 1; + + // Width value of the document, works together with the unit. + float width = 2; + + // Height value of the document, works together with the unit. + float height = 3; +} + +// A structured text document e.g. a PDF. +message Document { + // Describes the layout information of a [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the document. + message Layout { + // The type of TextSegment in the context of the original document. + enum TextSegmentType { + // Should not be used. + TEXT_SEGMENT_TYPE_UNSPECIFIED = 0; + + // The text segment is a token. e.g. word. + TOKEN = 1; + + // The text segment is a paragraph. + PARAGRAPH = 2; + + // The text segment is a form field. + FORM_FIELD = 3; + + // The text segment is the name part of a form field. It will be treated + // as child of another FORM_FIELD TextSegment if its span is subspan of + // another TextSegment with type FORM_FIELD. + FORM_FIELD_NAME = 4; + + // The text segment is the text content part of a form field. It will be + // treated as child of another FORM_FIELD TextSegment if its span is + // subspan of another TextSegment with type FORM_FIELD. + FORM_FIELD_CONTENTS = 5; + + // The text segment is a whole table, including headers, and all rows. + TABLE = 6; + + // The text segment is a table's headers. It will be treated as child of + // another TABLE TextSegment if its span is subspan of another TextSegment + // with type TABLE. + TABLE_HEADER = 7; + + // The text segment is a row in table. It will be treated as child of + // another TABLE TextSegment if its span is subspan of another TextSegment + // with type TABLE. + TABLE_ROW = 8; + + // The text segment is a cell in table. It will be treated as child of + // another TABLE_ROW TextSegment if its span is subspan of another + // TextSegment with type TABLE_ROW. + TABLE_CELL = 9; + } + + // Text Segment that represents a segment in + // [document_text][google.cloud.automl.v1beta1.Document.document_text]. + TextSegment text_segment = 1; + + // Page number of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the original document, starts + // from 1. + int32 page_number = 2; + + // The position of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the page. + // Contains exactly 4 + // + // [normalized_vertices][google.cloud.automl.v1beta1.BoundingPoly.normalized_vertices] + // and they are connected by edges in the order provided, which will + // represent a rectangle parallel to the frame. The + // [NormalizedVertex-s][google.cloud.automl.v1beta1.NormalizedVertex] are + // relative to the page. + // Coordinates are based on top-left as point (0,0). + BoundingPoly bounding_poly = 3; + + // The type of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in document. + TextSegmentType text_segment_type = 4; + } + + // An input config specifying the content of the document. + DocumentInputConfig input_config = 1; + + // The plain text version of this document. + TextSnippet document_text = 2; + + // Describes the layout of the document. + // Sorted by [page_number][]. + repeated Layout layout = 3; + + // The dimensions of the page in the document. + DocumentDimensions document_dimensions = 4; + + // Number of pages in the document. + int32 page_count = 5; +} + +// A representation of a row in a relational table. +message Row { + // The resource IDs of the column specs describing the columns of the row. + // If set must contain, but possibly in a different order, all input + // feature + // + // [column_spec_ids][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] + // of the Model this row is being passed to. + // Note: The below `values` field must match order of this field, if this + // field is set. + repeated string column_spec_ids = 2; + + // Required. The values of the row cells, given in the same order as the + // column_spec_ids, or, if not set, then in the same order as input + // feature + // + // [column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] + // of the Model this row is being passed to. + repeated google.protobuf.Value values = 3; +} + +// Example data used for training or prediction. +message ExamplePayload { + // Required. Input only. The example data. + oneof payload { + // Example image. + Image image = 1; + + // Example text. + TextSnippet text_snippet = 2; + + // Example document. + Document document = 4; + + // Example relational table row. + Row row = 3; + } +} diff --git a/google/cloud/automl_v1beta1/proto/data_stats.proto b/google/cloud/automl_v1beta1/proto/data_stats.proto new file mode 100644 index 00000000..c13a5d45 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/data_stats.proto @@ -0,0 +1,166 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// The data statistics of a series of values that share the same DataType. +message DataStats { + // The data statistics specific to a DataType. + oneof stats { + // The statistics for FLOAT64 DataType. + Float64Stats float64_stats = 3; + + // The statistics for STRING DataType. + StringStats string_stats = 4; + + // The statistics for TIMESTAMP DataType. + TimestampStats timestamp_stats = 5; + + // The statistics for ARRAY DataType. + ArrayStats array_stats = 6; + + // The statistics for STRUCT DataType. + StructStats struct_stats = 7; + + // The statistics for CATEGORY DataType. + CategoryStats category_stats = 8; + } + + // The number of distinct values. + int64 distinct_value_count = 1; + + // The number of values that are null. + int64 null_value_count = 2; + + // The number of values that are valid. + int64 valid_value_count = 9; +} + +// The data statistics of a series of FLOAT64 values. +message Float64Stats { + // A bucket of a histogram. + message HistogramBucket { + // The minimum value of the bucket, inclusive. + double min = 1; + + // The maximum value of the bucket, exclusive unless max = `"Infinity"`, in + // which case it's inclusive. + double max = 2; + + // The number of data values that are in the bucket, i.e. are between + // min and max values. + int64 count = 3; + } + + // The mean of the series. + double mean = 1; + + // The standard deviation of the series. + double standard_deviation = 2; + + // Ordered from 0 to k k-quantile values of the data series of n values. + // The value at index i is, approximately, the i*n/k-th smallest value in the + // series; for i = 0 and i = k these are, respectively, the min and max + // values. + repeated double quantiles = 3; + + // Histogram buckets of the data series. Sorted by the min value of the + // bucket, ascendingly, and the number of the buckets is dynamically + // generated. The buckets are non-overlapping and completely cover whole + // FLOAT64 range with min of first bucket being `"-Infinity"`, and max of + // the last one being `"Infinity"`. + repeated HistogramBucket histogram_buckets = 4; +} + +// The data statistics of a series of STRING values. +message StringStats { + // The statistics of a unigram. + message UnigramStats { + // The unigram. + string value = 1; + + // The number of occurrences of this unigram in the series. + int64 count = 2; + } + + // The statistics of the top 20 unigrams, ordered by + // [count][google.cloud.automl.v1beta1.StringStats.UnigramStats.count]. + repeated UnigramStats top_unigram_stats = 1; +} + +// The data statistics of a series of TIMESTAMP values. +message TimestampStats { + // Stats split by a defined in context granularity. + message GranularStats { + // A map from granularity key to example count for that key. + // E.g. for hour_of_day `13` means 1pm, or for month_of_year `5` means May). + map buckets = 1; + } + + // The string key is the pre-defined granularity. Currently supported: + // hour_of_day, day_of_week, month_of_year. + // Granularities finer that the granularity of timestamp data are not + // populated (e.g. if timestamps are at day granularity, then hour_of_day + // is not populated). + map granular_stats = 1; +} + +// The data statistics of a series of ARRAY values. +message ArrayStats { + // Stats of all the values of all arrays, as if they were a single long + // series of data. The type depends on the element type of the array. + DataStats member_stats = 2; +} + +// The data statistics of a series of STRUCT values. +message StructStats { + // Map from a field name of the struct to data stats aggregated over series + // of all data in that field across all the structs. + map field_stats = 1; +} + +// The data statistics of a series of CATEGORY values. +message CategoryStats { + // The statistics of a single CATEGORY value. + message SingleCategoryStats { + // The CATEGORY value. + string value = 1; + + // The number of occurrences of this value in the series. + int64 count = 2; + } + + // The statistics of the top 20 CATEGORY values, ordered by + // + // [count][google.cloud.automl.v1beta1.CategoryStats.SingleCategoryStats.count]. + repeated SingleCategoryStats top_category_stats = 1; +} + +// A correlation statistics between two series of DataType values. The series +// may have differing DataType-s, but within a single series the DataType must +// be the same. +message CorrelationStats { + // The correlation value using the Cramer's V measure. + double cramers_v = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/data_types.proto b/google/cloud/automl_v1beta1/proto/data_types.proto new file mode 100644 index 00000000..6f77f56b --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/data_types.proto @@ -0,0 +1,105 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// `TypeCode` is used as a part of +// [DataType][google.cloud.automl.v1beta1.DataType]. +enum TypeCode { + // Not specified. Should not be used. + TYPE_CODE_UNSPECIFIED = 0; + + // Encoded as `number`, or the strings `"NaN"`, `"Infinity"`, or + // `"-Infinity"`. + FLOAT64 = 3; + + // Must be between 0AD and 9999AD. Encoded as `string` according to + // [time_format][google.cloud.automl.v1beta1.DataType.time_format], or, if + // that format is not set, then in RFC 3339 `date-time` format, where + // `time-offset` = `"Z"` (e.g. 1985-04-12T23:20:50.52Z). + TIMESTAMP = 4; + + // Encoded as `string`. + STRING = 6; + + // Encoded as `list`, where the list elements are represented according to + // + // [list_element_type][google.cloud.automl.v1beta1.DataType.list_element_type]. + ARRAY = 8; + + // Encoded as `struct`, where field values are represented according to + // [struct_type][google.cloud.automl.v1beta1.DataType.struct_type]. + STRUCT = 9; + + // Values of this type are not further understood by AutoML, + // e.g. AutoML is unable to tell the order of values (as it could with + // FLOAT64), or is unable to say if one value contains another (as it + // could with STRING). + // Encoded as `string` (bytes should be base64-encoded, as described in RFC + // 4648, section 4). + CATEGORY = 10; +} + +// Indicated the type of data that can be stored in a structured data entity +// (e.g. a table). +message DataType { + // Details of DataType-s that need additional specification. + oneof details { + // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [ARRAY][google.cloud.automl.v1beta1.TypeCode.ARRAY], + // then `list_element_type` is the type of the elements. + DataType list_element_type = 2; + + // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [STRUCT][google.cloud.automl.v1beta1.TypeCode.STRUCT], then `struct_type` + // provides type information for the struct's fields. + StructType struct_type = 3; + + // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [TIMESTAMP][google.cloud.automl.v1beta1.TypeCode.TIMESTAMP] + // then `time_format` provides the format in which that time field is + // expressed. The time_format must either be one of: + // * `UNIX_SECONDS` + // * `UNIX_MILLISECONDS` + // * `UNIX_MICROSECONDS` + // * `UNIX_NANOSECONDS` + // (for respectively number of seconds, milliseconds, microseconds and + // nanoseconds since start of the Unix epoch); + // or be written in `strftime` syntax. If time_format is not set, then the + // default format as described on the type_code is used. + string time_format = 5; + } + + // Required. The [TypeCode][google.cloud.automl.v1beta1.TypeCode] for this type. + TypeCode type_code = 1; + + // If true, this DataType can also be `NULL`. In .CSV files `NULL` value is + // expressed as an empty string. + bool nullable = 4; +} + +// `StructType` defines the DataType-s of a [STRUCT][google.cloud.automl.v1beta1.TypeCode.STRUCT] type. +message StructType { + // Unordered map of struct field names to their data types. + // Fields cannot be added or removed via Update. Their names and + // data types are still mutable. + map fields = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/dataset.proto b/google/cloud/automl_v1beta1/proto/dataset.proto new file mode 100644 index 00000000..8d1b8d93 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/dataset.proto @@ -0,0 +1,96 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/image.proto"; +import "google/cloud/automl/v1beta1/tables.proto"; +import "google/cloud/automl/v1beta1/text.proto"; +import "google/cloud/automl/v1beta1/translation.proto"; +import "google/cloud/automl/v1beta1/video.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A workspace for solving a single, particular machine learning (ML) problem. +// A workspace contains examples that may be annotated. +message Dataset { + option (google.api.resource) = { + type: "automl.googleapis.com/Dataset" + pattern: "projects/{project}/locations/{location}/datasets/{dataset}" + }; + + // Required. + // The dataset metadata that is specific to the problem type. + oneof dataset_metadata { + // Metadata for a dataset used for translation. + TranslationDatasetMetadata translation_dataset_metadata = 23; + + // Metadata for a dataset used for image classification. + ImageClassificationDatasetMetadata image_classification_dataset_metadata = 24; + + // Metadata for a dataset used for text classification. + TextClassificationDatasetMetadata text_classification_dataset_metadata = 25; + + // Metadata for a dataset used for image object detection. + ImageObjectDetectionDatasetMetadata image_object_detection_dataset_metadata = 26; + + // Metadata for a dataset used for video classification. + VideoClassificationDatasetMetadata video_classification_dataset_metadata = 31; + + // Metadata for a dataset used for video object tracking. + VideoObjectTrackingDatasetMetadata video_object_tracking_dataset_metadata = 29; + + // Metadata for a dataset used for text extraction. + TextExtractionDatasetMetadata text_extraction_dataset_metadata = 28; + + // Metadata for a dataset used for text sentiment. + TextSentimentDatasetMetadata text_sentiment_dataset_metadata = 30; + + // Metadata for a dataset used for Tables. + TablesDatasetMetadata tables_dataset_metadata = 33; + } + + // Output only. The resource name of the dataset. + // Form: `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}` + string name = 1; + + // Required. The name of the dataset to show in the interface. The name can be + // up to 32 characters long and can consist only of ASCII Latin letters A-Z + // and a-z, underscores + // (_), and ASCII digits 0-9. + string display_name = 2; + + // User-provided description of the dataset. The description can be up to + // 25000 characters long. + string description = 3; + + // Output only. The number of examples in the dataset. + int32 example_count = 21; + + // Output only. Timestamp when this dataset was created. + google.protobuf.Timestamp create_time = 14; + + // Used to perform consistent read-modify-write updates. If not set, a blind + // "overwrite" update happens. + string etag = 17; +} diff --git a/google/cloud/automl_v1beta1/proto/detection.proto b/google/cloud/automl_v1beta1/proto/detection.proto new file mode 100644 index 00000000..c5864e20 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/detection.proto @@ -0,0 +1,135 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/geometry.proto"; +import "google/protobuf/duration.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Annotation details for image object detection. +message ImageObjectDetectionAnnotation { + // Output only. The rectangle representing the object location. + BoundingPoly bounding_box = 1; + + // Output only. The confidence that this annotation is positive for the parent example, + // value in [0, 1], higher means higher positivity confidence. + float score = 2; +} + +// Annotation details for video object tracking. +message VideoObjectTrackingAnnotation { + // Optional. The instance of the object, expressed as a positive integer. Used to tell + // apart objects of the same type (i.e. AnnotationSpec) when multiple are + // present on a single example. + // NOTE: Instance ID prediction quality is not a part of model evaluation and + // is done as best effort. Especially in cases when an entity goes + // off-screen for a longer time (minutes), when it comes back it may be given + // a new instance ID. + string instance_id = 1; + + // Required. A time (frame) of a video to which this annotation pertains. + // Represented as the duration since the video's start. + google.protobuf.Duration time_offset = 2; + + // Required. The rectangle representing the object location on the frame (i.e. + // at the time_offset of the video). + BoundingPoly bounding_box = 3; + + // Output only. The confidence that this annotation is positive for the video at + // the time_offset, value in [0, 1], higher means higher positivity + // confidence. For annotations created by the user the score is 1. When + // user approves an annotation, the original float score is kept (and not + // changed to 1). + float score = 4; +} + +// Bounding box matching model metrics for a single intersection-over-union +// threshold and multiple label match confidence thresholds. +message BoundingBoxMetricsEntry { + // Metrics for a single confidence threshold. + message ConfidenceMetricsEntry { + // Output only. The confidence threshold value used to compute the metrics. + float confidence_threshold = 1; + + // Output only. Recall under the given confidence threshold. + float recall = 2; + + // Output only. Precision under the given confidence threshold. + float precision = 3; + + // Output only. The harmonic mean of recall and precision. + float f1_score = 4; + } + + // Output only. The intersection-over-union threshold value used to compute + // this metrics entry. + float iou_threshold = 1; + + // Output only. The mean average precision, most often close to au_prc. + float mean_average_precision = 2; + + // Output only. Metrics for each label-match confidence_threshold from + // 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99. Precision-recall curve is + // derived from them. + repeated ConfidenceMetricsEntry confidence_metrics_entries = 3; +} + +// Model evaluation metrics for image object detection problems. +// Evaluates prediction quality of labeled bounding boxes. +message ImageObjectDetectionEvaluationMetrics { + // Output only. The total number of bounding boxes (i.e. summed over all + // images) the ground truth used to create this evaluation had. + int32 evaluated_bounding_box_count = 1; + + // Output only. The bounding boxes match metrics for each + // Intersection-over-union threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 + // and each label confidence threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 + // pair. + repeated BoundingBoxMetricsEntry bounding_box_metrics_entries = 2; + + // Output only. The single metric for bounding boxes evaluation: + // the mean_average_precision averaged over all bounding_box_metrics_entries. + float bounding_box_mean_average_precision = 3; +} + +// Model evaluation metrics for video object tracking problems. +// Evaluates prediction quality of both labeled bounding boxes and labeled +// tracks (i.e. series of bounding boxes sharing same label and instance ID). +message VideoObjectTrackingEvaluationMetrics { + // Output only. The number of video frames used to create this evaluation. + int32 evaluated_frame_count = 1; + + // Output only. The total number of bounding boxes (i.e. summed over all + // frames) the ground truth used to create this evaluation had. + int32 evaluated_bounding_box_count = 2; + + // Output only. The bounding boxes match metrics for each + // Intersection-over-union threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 + // and each label confidence threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 + // pair. + repeated BoundingBoxMetricsEntry bounding_box_metrics_entries = 4; + + // Output only. The single metric for bounding boxes evaluation: + // the mean_average_precision averaged over all bounding_box_metrics_entries. + float bounding_box_mean_average_precision = 6; +} diff --git a/google/cloud/automl_v1beta1/proto/geometry.proto b/google/cloud/automl_v1beta1/proto/geometry.proto new file mode 100644 index 00000000..d5654aac --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/geometry.proto @@ -0,0 +1,46 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A vertex represents a 2D point in the image. +// The normalized vertex coordinates are between 0 to 1 fractions relative to +// the original plane (image, video). E.g. if the plane (e.g. whole image) would +// have size 10 x 20 then a point with normalized coordinates (0.1, 0.3) would +// be at the position (1, 6) on that plane. +message NormalizedVertex { + // Required. Horizontal coordinate. + float x = 1; + + // Required. Vertical coordinate. + float y = 2; +} + +// A bounding polygon of a detected object on a plane. +// On output both vertices and normalized_vertices are provided. +// The polygon is formed by connecting vertices in the order they are listed. +message BoundingPoly { + // Output only . The bounding polygon normalized vertices. + repeated NormalizedVertex normalized_vertices = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/image.proto b/google/cloud/automl_v1beta1/proto/image.proto new file mode 100644 index 00000000..960eaeb0 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/image.proto @@ -0,0 +1,193 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/annotation_spec.proto"; +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "ImageProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Dataset metadata that is specific to image classification. +message ImageClassificationDatasetMetadata { + // Required. Type of the classification problem. + ClassificationType classification_type = 1; +} + +// Dataset metadata specific to image object detection. +message ImageObjectDetectionDatasetMetadata { + +} + +// Model metadata for image classification. +message ImageClassificationModelMetadata { + // Optional. The ID of the `base` model. If it is specified, the new model + // will be created based on the `base` model. Otherwise, the new model will be + // created from scratch. The `base` model must be in the same + // `project` and `location` as the new model to create, and have the same + // `model_type`. + string base_model_id = 1; + + // Required. The train budget of creating this model, expressed in hours. The + // actual `train_cost` will be equal or less than this value. + int64 train_budget = 2; + + // Output only. The actual train cost of creating this model, expressed in + // hours. If this model is created from a `base` model, the train cost used + // to create the `base` model are not included. + int64 train_cost = 3; + + // Output only. The reason that this create model operation stopped, + // e.g. `BUDGET_REACHED`, `MODEL_CONVERGED`. + string stop_reason = 5; + + // Optional. Type of the model. The available values are: + // * `cloud` - Model to be used via prediction calls to AutoML API. + // This is the default value. + // * `mobile-low-latency-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. Expected to have low latency, but + // may have lower prediction quality than other models. + // * `mobile-versatile-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. + // * `mobile-high-accuracy-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. Expected to have a higher + // latency, but should also have a higher prediction quality + // than other models. + // * `mobile-core-ml-low-latency-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with Core + // ML afterwards. Expected to have low latency, but may have + // lower prediction quality than other models. + // * `mobile-core-ml-versatile-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with Core + // ML afterwards. + // * `mobile-core-ml-high-accuracy-1` - A model that, in addition to + // providing prediction via AutoML API, can also be exported + // (see [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with + // Core ML afterwards. Expected to have a higher latency, but + // should also have a higher prediction quality than other + // models. + string model_type = 7; + + // Output only. An approximate number of online prediction QPS that can + // be supported by this model per each node on which it is deployed. + double node_qps = 13; + + // Output only. The number of nodes this model is deployed on. A node is an + // abstraction of a machine resource, which can handle online prediction QPS + // as given in the node_qps field. + int64 node_count = 14; +} + +// Model metadata specific to image object detection. +message ImageObjectDetectionModelMetadata { + // Optional. Type of the model. The available values are: + // * `cloud-high-accuracy-1` - (default) A model to be used via prediction + // calls to AutoML API. Expected to have a higher latency, but + // should also have a higher prediction quality than other + // models. + // * `cloud-low-latency-1` - A model to be used via prediction + // calls to AutoML API. Expected to have low latency, but may + // have lower prediction quality than other models. + // * `mobile-low-latency-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. Expected to have low latency, but + // may have lower prediction quality than other models. + // * `mobile-versatile-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. + // * `mobile-high-accuracy-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. Expected to have a higher + // latency, but should also have a higher prediction quality + // than other models. + string model_type = 1; + + // Output only. The number of nodes this model is deployed on. A node is an + // abstraction of a machine resource, which can handle online prediction QPS + // as given in the qps_per_node field. + int64 node_count = 3; + + // Output only. An approximate number of online prediction QPS that can + // be supported by this model per each node on which it is deployed. + double node_qps = 4; + + // Output only. The reason that this create model operation stopped, + // e.g. `BUDGET_REACHED`, `MODEL_CONVERGED`. + string stop_reason = 5; + + // The train budget of creating this model, expressed in milli node + // hours i.e. 1,000 value in this field means 1 node hour. The actual + // `train_cost` will be equal or less than this value. If further model + // training ceases to provide any improvements, it will stop without using + // full budget and the stop_reason will be `MODEL_CONVERGED`. + // Note, node_hour = actual_hour * number_of_nodes_invovled. + // For model type `cloud-high-accuracy-1`(default) and `cloud-low-latency-1`, + // the train budget must be between 20,000 and 900,000 milli node hours, + // inclusive. The default value is 216, 000 which represents one day in + // wall time. + // For model type `mobile-low-latency-1`, `mobile-versatile-1`, + // `mobile-high-accuracy-1`, `mobile-core-ml-low-latency-1`, + // `mobile-core-ml-versatile-1`, `mobile-core-ml-high-accuracy-1`, the train + // budget must be between 1,000 and 100,000 milli node hours, inclusive. + // The default value is 24, 000 which represents one day in wall time. + int64 train_budget_milli_node_hours = 6; + + // Output only. The actual train cost of creating this model, expressed in + // milli node hours, i.e. 1,000 value in this field means 1 node hour. + // Guaranteed to not exceed the train budget. + int64 train_cost_milli_node_hours = 7; +} + +// Model deployment metadata specific to Image Classification. +message ImageClassificationModelDeploymentMetadata { + // Input only. The number of nodes to deploy the model on. A node is an + // abstraction of a machine resource, which can handle online prediction QPS + // as given in the model's + // + // [node_qps][google.cloud.automl.v1beta1.ImageClassificationModelMetadata.node_qps]. + // Must be between 1 and 100, inclusive on both ends. + int64 node_count = 1; +} + +// Model deployment metadata specific to Image Object Detection. +message ImageObjectDetectionModelDeploymentMetadata { + // Input only. The number of nodes to deploy the model on. A node is an + // abstraction of a machine resource, which can handle online prediction QPS + // as given in the model's + // + // [qps_per_node][google.cloud.automl.v1beta1.ImageObjectDetectionModelMetadata.qps_per_node]. + // Must be between 1 and 100, inclusive on both ends. + int64 node_count = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/io.proto b/google/cloud/automl_v1beta1/proto/io.proto new file mode 100644 index 00000000..a9979383 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/io.proto @@ -0,0 +1,1132 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Input configuration for ImportData Action. +// +// The format of input depends on dataset_metadata the Dataset into which +// the import is happening has. As input source the +// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] +// is expected, unless specified otherwise. Additionally any input .CSV file +// by itself must be 100MB or smaller, unless specified otherwise. +// If an "example" file (that is, image, video etc.) with identical content +// (even if it had different GCS_FILE_PATH) is mentioned multiple times, then +// its label, bounding boxes etc. are appended. The same file should be always +// provided with the same ML_USE and GCS_FILE_PATH, if it is not, then +// these values are nondeterministically selected from the given ones. +// +// The formats are represented in EBNF with commas being literal and with +// non-terminal symbols defined near the end of this comment. The formats are: +// +// * For Image Classification: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH,LABEL,LABEL,... +// GCS_FILE_PATH leads to image of up to 30MB in size. Supported +// extensions: .JPEG, .GIF, .PNG, .WEBP, .BMP, .TIFF, .ICO +// For MULTICLASS classification type, at most one LABEL is allowed +// per image. If an image has not yet been labeled, then it should be +// mentioned just once with no LABEL. +// Some sample rows: +// TRAIN,gs://folder/image1.jpg,daisy +// TEST,gs://folder/image2.jpg,dandelion,tulip,rose +// UNASSIGNED,gs://folder/image3.jpg,daisy +// UNASSIGNED,gs://folder/image4.jpg +// +// * For Image Object Detection: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH,(LABEL,BOUNDING_BOX | ,,,,,,,) +// GCS_FILE_PATH leads to image of up to 30MB in size. Supported +// extensions: .JPEG, .GIF, .PNG. +// Each image is assumed to be exhaustively labeled. The minimum +// allowed BOUNDING_BOX edge length is 0.01, and no more than 500 +// BOUNDING_BOX-es per image are allowed (one BOUNDING_BOX is defined +// per line). If an image has not yet been labeled, then it should be +// mentioned just once with no LABEL and the ",,,,,,," in place of the +// BOUNDING_BOX. For images which are known to not contain any +// bounding boxes, they should be labelled explictly as +// "NEGATIVE_IMAGE", followed by ",,,,,,," in place of the +// BOUNDING_BOX. +// Sample rows: +// TRAIN,gs://folder/image1.png,car,0.1,0.1,,,0.3,0.3,, +// TRAIN,gs://folder/image1.png,bike,.7,.6,,,.8,.9,, +// UNASSIGNED,gs://folder/im2.png,car,0.1,0.1,0.2,0.1,0.2,0.3,0.1,0.3 +// TEST,gs://folder/im3.png,,,,,,,,, +// TRAIN,gs://folder/im4.png,NEGATIVE_IMAGE,,,,,,,,, +// +// * For Video Classification: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH +// where ML_USE VALIDATE value should not be used. The GCS_FILE_PATH +// should lead to another .csv file which describes examples that have +// given ML_USE, using the following row format: +// GCS_FILE_PATH,(LABEL,TIME_SEGMENT_START,TIME_SEGMENT_END | ,,) +// Here GCS_FILE_PATH leads to a video of up to 50GB in size and up +// to 3h duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. +// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the +// length of the video, and end has to be after the start. Any segment +// of a video which has one or more labels on it, is considered a +// hard negative for all other labels. Any segment with no labels on +// it is considered to be unknown. If a whole video is unknown, then +// it shuold be mentioned just once with ",," in place of LABEL, +// TIME_SEGMENT_START,TIME_SEGMENT_END. +// Sample top level CSV file: +// TRAIN,gs://folder/train_videos.csv +// TEST,gs://folder/test_videos.csv +// UNASSIGNED,gs://folder/other_videos.csv +// Sample rows of a CSV file for a particular ML_USE: +// gs://folder/video1.avi,car,120,180.000021 +// gs://folder/video1.avi,bike,150,180.000021 +// gs://folder/vid2.avi,car,0,60.5 +// gs://folder/vid3.avi,,, +// +// * For Video Object Tracking: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH +// where ML_USE VALIDATE value should not be used. The GCS_FILE_PATH +// should lead to another .csv file which describes examples that have +// given ML_USE, using one of the following row format: +// GCS_FILE_PATH,LABEL,[INSTANCE_ID],TIMESTAMP,BOUNDING_BOX +// or +// GCS_FILE_PATH,,,,,,,,,, +// Here GCS_FILE_PATH leads to a video of up to 50GB in size and up +// to 3h duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. +// Providing INSTANCE_IDs can help to obtain a better model. When +// a specific labeled entity leaves the video frame, and shows up +// afterwards it is not required, albeit preferable, that the same +// INSTANCE_ID is given to it. +// TIMESTAMP must be within the length of the video, the +// BOUNDING_BOX is assumed to be drawn on the closest video's frame +// to the TIMESTAMP. Any mentioned by the TIMESTAMP frame is expected +// to be exhaustively labeled and no more than 500 BOUNDING_BOX-es per +// frame are allowed. If a whole video is unknown, then it should be +// mentioned just once with ",,,,,,,,,," in place of LABEL, +// [INSTANCE_ID],TIMESTAMP,BOUNDING_BOX. +// Sample top level CSV file: +// TRAIN,gs://folder/train_videos.csv +// TEST,gs://folder/test_videos.csv +// UNASSIGNED,gs://folder/other_videos.csv +// Seven sample rows of a CSV file for a particular ML_USE: +// gs://folder/video1.avi,car,1,12.10,0.8,0.8,0.9,0.8,0.9,0.9,0.8,0.9 +// gs://folder/video1.avi,car,1,12.90,0.4,0.8,0.5,0.8,0.5,0.9,0.4,0.9 +// gs://folder/video1.avi,car,2,12.10,.4,.2,.5,.2,.5,.3,.4,.3 +// gs://folder/video1.avi,car,2,12.90,.8,.2,,,.9,.3,, +// gs://folder/video1.avi,bike,,12.50,.45,.45,,,.55,.55,, +// gs://folder/video2.avi,car,1,0,.1,.9,,,.9,.1,, +// gs://folder/video2.avi,,,,,,,,,,, +// * For Text Extraction: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH +// GCS_FILE_PATH leads to a .JSONL (that is, JSON Lines) file which +// either imports text in-line or as documents. Any given +// .JSONL file must be 100MB or smaller. +// The in-line .JSONL file contains, per line, a proto that wraps a +// TextSnippet proto (in json representation) followed by one or more +// AnnotationPayload protos (called annotations), which have +// display_name and text_extraction detail populated. The given text +// is expected to be annotated exhaustively, for example, if you look +// for animals and text contains "dolphin" that is not labeled, then +// "dolphin" is assumed to not be an animal. Any given text snippet +// content must be 10KB or smaller, and also be UTF-8 NFC encoded +// (ASCII already is). +// The document .JSONL file contains, per line, a proto that wraps a +// Document proto. The Document proto must have either document_text +// or input_config set. In document_text case, the Document proto may +// also contain the spatial information of the document, including +// layout, document dimension and page number. In input_config case, +// only PDF documents are supported now, and each document may be up +// to 2MB large. Currently, annotations on documents cannot be +// specified at import. +// Three sample CSV rows: +// TRAIN,gs://folder/file1.jsonl +// VALIDATE,gs://folder/file2.jsonl +// TEST,gs://folder/file3.jsonl +// Sample in-line JSON Lines file for entity extraction (presented here +// with artificial line breaks, but the only actual line break is +// denoted by \n).: +// { +// "document": { +// "document_text": {"content": "dog cat"} +// "layout": [ +// { +// "text_segment": { +// "start_offset": 0, +// "end_offset": 3, +// }, +// "page_number": 1, +// "bounding_poly": { +// "normalized_vertices": [ +// {"x": 0.1, "y": 0.1}, +// {"x": 0.1, "y": 0.3}, +// {"x": 0.3, "y": 0.3}, +// {"x": 0.3, "y": 0.1}, +// ], +// }, +// "text_segment_type": TOKEN, +// }, +// { +// "text_segment": { +// "start_offset": 4, +// "end_offset": 7, +// }, +// "page_number": 1, +// "bounding_poly": { +// "normalized_vertices": [ +// {"x": 0.4, "y": 0.1}, +// {"x": 0.4, "y": 0.3}, +// {"x": 0.8, "y": 0.3}, +// {"x": 0.8, "y": 0.1}, +// ], +// }, +// "text_segment_type": TOKEN, +// } +// +// ], +// "document_dimensions": { +// "width": 8.27, +// "height": 11.69, +// "unit": INCH, +// } +// "page_count": 1, +// }, +// "annotations": [ +// { +// "display_name": "animal", +// "text_extraction": {"text_segment": {"start_offset": 0, +// "end_offset": 3}} +// }, +// { +// "display_name": "animal", +// "text_extraction": {"text_segment": {"start_offset": 4, +// "end_offset": 7}} +// } +// ], +// }\n +// { +// "text_snippet": { +// "content": "This dog is good." +// }, +// "annotations": [ +// { +// "display_name": "animal", +// "text_extraction": { +// "text_segment": {"start_offset": 5, "end_offset": 8} +// } +// } +// ] +// } +// Sample document JSON Lines file (presented here with artificial line +// breaks, but the only actual line break is denoted by \n).: +// { +// "document": { +// "input_config": { +// "gcs_source": { "input_uris": [ "gs://folder/document1.pdf" ] +// } +// } +// } +// }\n +// { +// "document": { +// "input_config": { +// "gcs_source": { "input_uris": [ "gs://folder/document2.pdf" ] +// } +// } +// } +// } +// +// * For Text Classification: +// CSV file(s) with each line in format: +// ML_USE,(TEXT_SNIPPET | GCS_FILE_PATH),LABEL,LABEL,... +// TEXT_SNIPPET and GCS_FILE_PATH are distinguished by a pattern. If +// the column content is a valid gcs file path, i.e. prefixed by +// "gs://", it will be treated as a GCS_FILE_PATH, else if the content +// is enclosed within double quotes (""), it is +// treated as a TEXT_SNIPPET. In the GCS_FILE_PATH case, the path +// must lead to a .txt file with UTF-8 encoding, for example, +// "gs://folder/content.txt", and the content in it is extracted +// as a text snippet. In TEXT_SNIPPET case, the column content +// excluding quotes is treated as to be imported text snippet. In +// both cases, the text snippet/file size must be within 128kB. +// Maximum 100 unique labels are allowed per CSV row. +// Sample rows: +// TRAIN,"They have bad food and very rude",RudeService,BadFood +// TRAIN,gs://folder/content.txt,SlowService +// TEST,"Typically always bad service there.",RudeService +// VALIDATE,"Stomach ache to go.",BadFood +// +// * For Text Sentiment: +// CSV file(s) with each line in format: +// ML_USE,(TEXT_SNIPPET | GCS_FILE_PATH),SENTIMENT +// TEXT_SNIPPET and GCS_FILE_PATH are distinguished by a pattern. If +// the column content is a valid gcs file path, that is, prefixed by +// "gs://", it is treated as a GCS_FILE_PATH, otherwise it is treated +// as a TEXT_SNIPPET. In the GCS_FILE_PATH case, the path +// must lead to a .txt file with UTF-8 encoding, for example, +// "gs://folder/content.txt", and the content in it is extracted +// as a text snippet. In TEXT_SNIPPET case, the column content itself +// is treated as to be imported text snippet. In both cases, the +// text snippet must be up to 500 characters long. +// Sample rows: +// TRAIN,"@freewrytin this is way too good for your product",2 +// TRAIN,"I need this product so bad",3 +// TEST,"Thank you for this product.",4 +// VALIDATE,gs://folder/content.txt,2 +// +// * For Tables: +// Either +// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] or +// +// [bigquery_source][google.cloud.automl.v1beta1.InputConfig.bigquery_source] +// can be used. All inputs is concatenated into a single +// +// [primary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_name] +// For gcs_source: +// CSV file(s), where the first row of the first file is the header, +// containing unique column names. If the first row of a subsequent +// file is the same as the header, then it is also treated as a +// header. All other rows contain values for the corresponding +// columns. +// Each .CSV file by itself must be 10GB or smaller, and their total +// size must be 100GB or smaller. +// First three sample rows of a CSV file: +// "Id","First Name","Last Name","Dob","Addresses" +// +// "1","John","Doe","1968-01-22","[{"status":"current","address":"123_First_Avenue","city":"Seattle","state":"WA","zip":"11111","numberOfYears":"1"},{"status":"previous","address":"456_Main_Street","city":"Portland","state":"OR","zip":"22222","numberOfYears":"5"}]" +// +// "2","Jane","Doe","1980-10-16","[{"status":"current","address":"789_Any_Avenue","city":"Albany","state":"NY","zip":"33333","numberOfYears":"2"},{"status":"previous","address":"321_Main_Street","city":"Hoboken","state":"NJ","zip":"44444","numberOfYears":"3"}]} +// For bigquery_source: +// An URI of a BigQuery table. The user data size of the BigQuery +// table must be 100GB or smaller. +// An imported table must have between 2 and 1,000 columns, inclusive, +// and between 1000 and 100,000,000 rows, inclusive. There are at most 5 +// import data running in parallel. +// Definitions: +// ML_USE = "TRAIN" | "VALIDATE" | "TEST" | "UNASSIGNED" +// Describes how the given example (file) should be used for model +// training. "UNASSIGNED" can be used when user has no preference. +// GCS_FILE_PATH = A path to file on GCS, e.g. "gs://folder/image1.png". +// LABEL = A display name of an object on an image, video etc., e.g. "dog". +// Must be up to 32 characters long and can consist only of ASCII +// Latin letters A-Z and a-z, underscores(_), and ASCII digits 0-9. +// For each label an AnnotationSpec is created which display_name +// becomes the label; AnnotationSpecs are given back in predictions. +// INSTANCE_ID = A positive integer that identifies a specific instance of a +// labeled entity on an example. Used e.g. to track two cars on +// a video while being able to tell apart which one is which. +// BOUNDING_BOX = VERTEX,VERTEX,VERTEX,VERTEX | VERTEX,,,VERTEX,, +// A rectangle parallel to the frame of the example (image, +// video). If 4 vertices are given they are connected by edges +// in the order provided, if 2 are given they are recognized +// as diagonally opposite vertices of the rectangle. +// VERTEX = COORDINATE,COORDINATE +// First coordinate is horizontal (x), the second is vertical (y). +// COORDINATE = A float in 0 to 1 range, relative to total length of +// image or video in given dimension. For fractions the +// leading non-decimal 0 can be omitted (i.e. 0.3 = .3). +// Point 0,0 is in top left. +// TIME_SEGMENT_START = TIME_OFFSET +// Expresses a beginning, inclusive, of a time segment +// within an example that has a time dimension +// (e.g. video). +// TIME_SEGMENT_END = TIME_OFFSET +// Expresses an end, exclusive, of a time segment within +// an example that has a time dimension (e.g. video). +// TIME_OFFSET = A number of seconds as measured from the start of an +// example (e.g. video). Fractions are allowed, up to a +// microsecond precision. "inf" is allowed, and it means the end +// of the example. +// TEXT_SNIPPET = A content of a text snippet, UTF-8 encoded, enclosed within +// double quotes (""). +// SENTIMENT = An integer between 0 and +// Dataset.text_sentiment_dataset_metadata.sentiment_max +// (inclusive). Describes the ordinal of the sentiment - higher +// value means a more positive sentiment. All the values are +// completely relative, i.e. neither 0 needs to mean a negative or +// neutral sentiment nor sentiment_max needs to mean a positive one +// - it is just required that 0 is the least positive sentiment +// in the data, and sentiment_max is the most positive one. +// The SENTIMENT shouldn't be confused with "score" or "magnitude" +// from the previous Natural Language Sentiment Analysis API. +// All SENTIMENT values between 0 and sentiment_max must be +// represented in the imported data. On prediction the same 0 to +// sentiment_max range will be used. The difference between +// neighboring sentiment values needs not to be uniform, e.g. 1 and +// 2 may be similar whereas the difference between 2 and 3 may be +// huge. +// +// Errors: +// If any of the provided CSV files can't be parsed or if more than certain +// percent of CSV rows cannot be processed then the operation fails and +// nothing is imported. Regardless of overall success or failure the per-row +// failures, up to a certain count cap, is listed in +// Operation.metadata.partial_failures. +// +message InputConfig { + // The source of the input. + oneof source { + // The Google Cloud Storage location for the input content. + // In ImportData, the gcs_source points to a csv with structure described in + // the comment. + GcsSource gcs_source = 1; + + // The BigQuery location for the input content. + BigQuerySource bigquery_source = 3; + } + + // Additional domain-specific parameters describing the semantic of the + // imported data, any string must be up to 25000 + // characters long. + // + // * For Tables: + // `schema_inference_version` - (integer) Required. The version of the + // algorithm that should be used for the initial inference of the + // schema (columns' DataTypes) of the table the data is being imported + // into. Allowed values: "1". + map params = 2; +} + +// Input configuration for BatchPredict Action. +// +// The format of input depends on the ML problem of the model used for +// prediction. As input source the +// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] +// is expected, unless specified otherwise. +// +// The formats are represented in EBNF with commas being literal and with +// non-terminal symbols defined near the end of this comment. The formats +// are: +// +// * For Image Classification: +// CSV file(s) with each line having just a single column: +// GCS_FILE_PATH +// which leads to image of up to 30MB in size. Supported +// extensions: .JPEG, .GIF, .PNG. This path is treated as the ID in +// the Batch predict output. +// Three sample rows: +// gs://folder/image1.jpeg +// gs://folder/image2.gif +// gs://folder/image3.png +// +// * For Image Object Detection: +// CSV file(s) with each line having just a single column: +// GCS_FILE_PATH +// which leads to image of up to 30MB in size. Supported +// extensions: .JPEG, .GIF, .PNG. This path is treated as the ID in +// the Batch predict output. +// Three sample rows: +// gs://folder/image1.jpeg +// gs://folder/image2.gif +// gs://folder/image3.png +// * For Video Classification: +// CSV file(s) with each line in format: +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END +// GCS_FILE_PATH leads to video of up to 50GB in size and up to 3h +// duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. +// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the +// length of the video, and end has to be after the start. +// Three sample rows: +// gs://folder/video1.mp4,10,40 +// gs://folder/video1.mp4,20,60 +// gs://folder/vid2.mov,0,inf +// +// * For Video Object Tracking: +// CSV file(s) with each line in format: +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END +// GCS_FILE_PATH leads to video of up to 50GB in size and up to 3h +// duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. +// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the +// length of the video, and end has to be after the start. +// Three sample rows: +// gs://folder/video1.mp4,10,240 +// gs://folder/video1.mp4,300,360 +// gs://folder/vid2.mov,0,inf +// * For Text Classification: +// CSV file(s) with each line having just a single column: +// GCS_FILE_PATH | TEXT_SNIPPET +// Any given text file can have size upto 128kB. +// Any given text snippet content must have 60,000 characters or less. +// Three sample rows: +// gs://folder/text1.txt +// "Some text content to predict" +// gs://folder/text3.pdf +// Supported file extensions: .txt, .pdf +// +// * For Text Sentiment: +// CSV file(s) with each line having just a single column: +// GCS_FILE_PATH | TEXT_SNIPPET +// Any given text file can have size upto 128kB. +// Any given text snippet content must have 500 characters or less. +// Three sample rows: +// gs://folder/text1.txt +// "Some text content to predict" +// gs://folder/text3.pdf +// Supported file extensions: .txt, .pdf +// +// * For Text Extraction +// .JSONL (i.e. JSON Lines) file(s) which either provide text in-line or +// as documents (for a single BatchPredict call only one of the these +// formats may be used). +// The in-line .JSONL file(s) contain per line a proto that +// wraps a temporary user-assigned TextSnippet ID (string up to 2000 +// characters long) called "id", a TextSnippet proto (in +// json representation) and zero or more TextFeature protos. Any given +// text snippet content must have 30,000 characters or less, and also +// be UTF-8 NFC encoded (ASCII already is). The IDs provided should be +// unique. +// The document .JSONL file(s) contain, per line, a proto that wraps a +// Document proto with input_config set. Only PDF documents are +// supported now, and each document must be up to 2MB large. +// Any given .JSONL file must be 100MB or smaller, and no more than 20 +// files may be given. +// Sample in-line JSON Lines file (presented here with artificial line +// breaks, but the only actual line break is denoted by \n): +// { +// "id": "my_first_id", +// "text_snippet": { "content": "dog car cat"}, +// "text_features": [ +// { +// "text_segment": {"start_offset": 4, "end_offset": 6}, +// "structural_type": PARAGRAPH, +// "bounding_poly": { +// "normalized_vertices": [ +// {"x": 0.1, "y": 0.1}, +// {"x": 0.1, "y": 0.3}, +// {"x": 0.3, "y": 0.3}, +// {"x": 0.3, "y": 0.1}, +// ] +// }, +// } +// ], +// }\n +// { +// "id": "2", +// "text_snippet": { +// "content": "An elaborate content", +// "mime_type": "text/plain" +// } +// } +// Sample document JSON Lines file (presented here with artificial line +// breaks, but the only actual line break is denoted by \n).: +// { +// "document": { +// "input_config": { +// "gcs_source": { "input_uris": [ "gs://folder/document1.pdf" ] +// } +// } +// } +// }\n +// { +// "document": { +// "input_config": { +// "gcs_source": { "input_uris": [ "gs://folder/document2.pdf" ] +// } +// } +// } +// } +// +// * For Tables: +// Either +// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] or +// +// [bigquery_source][google.cloud.automl.v1beta1.InputConfig.bigquery_source]. +// GCS case: +// CSV file(s), each by itself 10GB or smaller and total size must be +// 100GB or smaller, where first file must have a header containing +// column names. If the first row of a subsequent file is the same as +// the header, then it is also treated as a header. All other rows +// contain values for the corresponding columns. +// The column names must contain the model's +// +// [input_feature_column_specs'][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] +// +// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] +// (order doesn't matter). The columns corresponding to the model's +// input feature column specs must contain values compatible with the +// column spec's data types. Prediction on all the rows, i.e. the CSV +// lines, will be attempted. For FORECASTING +// +// [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: +// all columns having +// +// [TIME_SERIES_AVAILABLE_PAST_ONLY][google.cloud.automl.v1beta1.ColumnSpec.ForecastingMetadata.ColumnType] +// type will be ignored. +// First three sample rows of a CSV file: +// "First Name","Last Name","Dob","Addresses" +// +// "John","Doe","1968-01-22","[{"status":"current","address":"123_First_Avenue","city":"Seattle","state":"WA","zip":"11111","numberOfYears":"1"},{"status":"previous","address":"456_Main_Street","city":"Portland","state":"OR","zip":"22222","numberOfYears":"5"}]" +// +// "Jane","Doe","1980-10-16","[{"status":"current","address":"789_Any_Avenue","city":"Albany","state":"NY","zip":"33333","numberOfYears":"2"},{"status":"previous","address":"321_Main_Street","city":"Hoboken","state":"NJ","zip":"44444","numberOfYears":"3"}]} +// BigQuery case: +// An URI of a BigQuery table. The user data size of the BigQuery +// table must be 100GB or smaller. +// The column names must contain the model's +// +// [input_feature_column_specs'][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] +// +// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] +// (order doesn't matter). The columns corresponding to the model's +// input feature column specs must contain values compatible with the +// column spec's data types. Prediction on all the rows of the table +// will be attempted. For FORECASTING +// +// [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: +// all columns having +// +// [TIME_SERIES_AVAILABLE_PAST_ONLY][google.cloud.automl.v1beta1.ColumnSpec.ForecastingMetadata.ColumnType] +// type will be ignored. +// +// Definitions: +// GCS_FILE_PATH = A path to file on GCS, e.g. "gs://folder/video.avi". +// TEXT_SNIPPET = A content of a text snippet, UTF-8 encoded, enclosed within +// double quotes ("") +// TIME_SEGMENT_START = TIME_OFFSET +// Expresses a beginning, inclusive, of a time segment +// within an +// example that has a time dimension (e.g. video). +// TIME_SEGMENT_END = TIME_OFFSET +// Expresses an end, exclusive, of a time segment within +// an example that has a time dimension (e.g. video). +// TIME_OFFSET = A number of seconds as measured from the start of an +// example (e.g. video). Fractions are allowed, up to a +// microsecond precision. "inf" is allowed and it means the end +// of the example. +// +// Errors: +// If any of the provided CSV files can't be parsed or if more than certain +// percent of CSV rows cannot be processed then the operation fails and +// prediction does not happen. Regardless of overall success or failure the +// per-row failures, up to a certain count cap, will be listed in +// Operation.metadata.partial_failures. +message BatchPredictInputConfig { + // Required. The source of the input. + oneof source { + // The Google Cloud Storage location for the input content. + GcsSource gcs_source = 1; + + // The BigQuery location for the input content. + BigQuerySource bigquery_source = 2; + } +} + +// Input configuration of a [Document][google.cloud.automl.v1beta1.Document]. +message DocumentInputConfig { + // The Google Cloud Storage location of the document file. Only a single path + // should be given. + // Max supported size: 512MB. + // Supported extensions: .PDF. + GcsSource gcs_source = 1; +} + +// * For Translation: +// CSV file `translation.csv`, with each line in format: +// ML_USE,GCS_FILE_PATH +// GCS_FILE_PATH leads to a .TSV file which describes examples that have +// given ML_USE, using the following row format per line: +// TEXT_SNIPPET (in source language) \t TEXT_SNIPPET (in target +// language) +// +// * For Tables: +// Output depends on whether the dataset was imported from GCS or +// BigQuery. +// GCS case: +// +// [gcs_destination][google.cloud.automl.v1beta1.OutputConfig.gcs_destination] +// must be set. Exported are CSV file(s) `tables_1.csv`, +// `tables_2.csv`,...,`tables_N.csv` with each having as header line +// the table's column names, and all other lines contain values for +// the header columns. +// BigQuery case: +// +// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] +// pointing to a BigQuery project must be set. In the given project a +// new dataset will be created with name +// +// `export_data__` +// where will be made +// BigQuery-dataset-name compatible (e.g. most special characters will +// become underscores), and timestamp will be in +// YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" format. In that +// dataset a new table called `primary_table` will be created, and +// filled with precisely the same data as this obtained on import. +message OutputConfig { + // Required. The destination of the output. + oneof destination { + // The Google Cloud Storage location where the output is to be written to. + // For Image Object Detection, Text Extraction, Video Classification and + // Tables, in the given directory a new directory will be created with name: + // export_data-- where + // timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format. All export + // output will be written into that directory. + GcsDestination gcs_destination = 1; + + // The BigQuery location where the output is to be written to. + BigQueryDestination bigquery_destination = 2; + } +} + +// Output configuration for BatchPredict Action. +// +// As destination the +// +// [gcs_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.gcs_destination] +// must be set unless specified otherwise for a domain. If gcs_destination is +// set then in the given directory a new directory is created. Its name +// will be +// "prediction--", +// where timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format. The contents +// of it depends on the ML problem the predictions are made for. +// +// * For Image Classification: +// In the created directory files `image_classification_1.jsonl`, +// `image_classification_2.jsonl`,...,`image_classification_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of the successfully predicted images and annotations. +// A single image will be listed only once with all its annotations, +// and its annotations will never be split across files. +// Each .JSONL file will contain, per line, a JSON representation of a +// proto that wraps image's "ID" : "" followed by a list of +// zero or more AnnotationPayload protos (called annotations), which +// have classification detail populated. +// If prediction for any image failed (partially or completely), then an +// additional `errors_1.jsonl`, `errors_2.jsonl`,..., `errors_N.jsonl` +// files will be created (N depends on total number of failed +// predictions). These files will have a JSON representation of a proto +// that wraps the same "ID" : "" but here followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`fields. +// +// * For Image Object Detection: +// In the created directory files `image_object_detection_1.jsonl`, +// `image_object_detection_2.jsonl`,...,`image_object_detection_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of the successfully predicted images and annotations. +// Each .JSONL file will contain, per line, a JSON representation of a +// proto that wraps image's "ID" : "" followed by a list of +// zero or more AnnotationPayload protos (called annotations), which +// have image_object_detection detail populated. A single image will +// be listed only once with all its annotations, and its annotations +// will never be split across files. +// If prediction for any image failed (partially or completely), then +// additional `errors_1.jsonl`, `errors_2.jsonl`,..., `errors_N.jsonl` +// files will be created (N depends on total number of failed +// predictions). These files will have a JSON representation of a proto +// that wraps the same "ID" : "" but here followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`fields. +// * For Video Classification: +// In the created directory a video_classification.csv file, and a .JSON +// file per each video classification requested in the input (i.e. each +// line in given CSV(s)), will be created. +// +// The format of video_classification.csv is: +// +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END,JSON_FILE_NAME,STATUS +// where: +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END = matches 1 to 1 +// the prediction input lines (i.e. video_classification.csv has +// precisely the same number of lines as the prediction input had.) +// JSON_FILE_NAME = Name of .JSON file in the output directory, which +// contains prediction responses for the video time segment. +// STATUS = "OK" if prediction completed successfully, or an error code +// with message otherwise. If STATUS is not "OK" then the .JSON file +// for that line may not exist or be empty. +// +// Each .JSON file, assuming STATUS is "OK", will contain a list of +// AnnotationPayload protos in JSON format, which are the predictions +// for the video time segment the file is assigned to in the +// video_classification.csv. All AnnotationPayload protos will have +// video_classification field set, and will be sorted by +// video_classification.type field (note that the returned types are +// governed by `classifaction_types` parameter in +// [PredictService.BatchPredictRequest.params][]). +// +// * For Video Object Tracking: +// In the created directory a video_object_tracking.csv file will be +// created, and multiple files video_object_trackinng_1.json, +// video_object_trackinng_2.json,..., video_object_trackinng_N.json, +// where N is the number of requests in the input (i.e. the number of +// lines in given CSV(s)). +// +// The format of video_object_tracking.csv is: +// +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END,JSON_FILE_NAME,STATUS +// where: +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END = matches 1 to 1 +// the prediction input lines (i.e. video_object_tracking.csv has +// precisely the same number of lines as the prediction input had.) +// JSON_FILE_NAME = Name of .JSON file in the output directory, which +// contains prediction responses for the video time segment. +// STATUS = "OK" if prediction completed successfully, or an error +// code with message otherwise. If STATUS is not "OK" then the .JSON +// file for that line may not exist or be empty. +// +// Each .JSON file, assuming STATUS is "OK", will contain a list of +// AnnotationPayload protos in JSON format, which are the predictions +// for each frame of the video time segment the file is assigned to in +// video_object_tracking.csv. All AnnotationPayload protos will have +// video_object_tracking field set. +// * For Text Classification: +// In the created directory files `text_classification_1.jsonl`, +// `text_classification_2.jsonl`,...,`text_classification_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of inputs and annotations found. +// +// Each .JSONL file will contain, per line, a JSON representation of a +// proto that wraps input text snippet or input text file and a list of +// zero or more AnnotationPayload protos (called annotations), which +// have classification detail populated. A single text snippet or file +// will be listed only once with all its annotations, and its +// annotations will never be split across files. +// +// If prediction for any text snippet or file failed (partially or +// completely), then additional `errors_1.jsonl`, `errors_2.jsonl`,..., +// `errors_N.jsonl` files will be created (N depends on total number of +// failed predictions). These files will have a JSON representation of a +// proto that wraps input text snippet or input text file followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`. +// +// * For Text Sentiment: +// In the created directory files `text_sentiment_1.jsonl`, +// `text_sentiment_2.jsonl`,...,`text_sentiment_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of inputs and annotations found. +// +// Each .JSONL file will contain, per line, a JSON representation of a +// proto that wraps input text snippet or input text file and a list of +// zero or more AnnotationPayload protos (called annotations), which +// have text_sentiment detail populated. A single text snippet or file +// will be listed only once with all its annotations, and its +// annotations will never be split across files. +// +// If prediction for any text snippet or file failed (partially or +// completely), then additional `errors_1.jsonl`, `errors_2.jsonl`,..., +// `errors_N.jsonl` files will be created (N depends on total number of +// failed predictions). These files will have a JSON representation of a +// proto that wraps input text snippet or input text file followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`. +// +// * For Text Extraction: +// In the created directory files `text_extraction_1.jsonl`, +// `text_extraction_2.jsonl`,...,`text_extraction_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of inputs and annotations found. +// The contents of these .JSONL file(s) depend on whether the input +// used inline text, or documents. +// If input was inline, then each .JSONL file will contain, per line, +// a JSON representation of a proto that wraps given in request text +// snippet's "id" (if specified), followed by input text snippet, +// and a list of zero or more +// AnnotationPayload protos (called annotations), which have +// text_extraction detail populated. A single text snippet will be +// listed only once with all its annotations, and its annotations will +// never be split across files. +// If input used documents, then each .JSONL file will contain, per +// line, a JSON representation of a proto that wraps given in request +// document proto, followed by its OCR-ed representation in the form +// of a text snippet, finally followed by a list of zero or more +// AnnotationPayload protos (called annotations), which have +// text_extraction detail populated and refer, via their indices, to +// the OCR-ed text snippet. A single document (and its text snippet) +// will be listed only once with all its annotations, and its +// annotations will never be split across files. +// If prediction for any text snippet failed (partially or completely), +// then additional `errors_1.jsonl`, `errors_2.jsonl`,..., +// `errors_N.jsonl` files will be created (N depends on total number of +// failed predictions). These files will have a JSON representation of a +// proto that wraps either the "id" : "" (in case of inline) +// or the document proto (in case of document) but here followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`. +// +// * For Tables: +// Output depends on whether +// +// [gcs_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.gcs_destination] +// or +// +// [bigquery_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.bigquery_destination] +// is set (either is allowed). +// GCS case: +// In the created directory files `tables_1.csv`, `tables_2.csv`,..., +// `tables_N.csv` will be created, where N may be 1, and depends on +// the total number of the successfully predicted rows. +// For all CLASSIFICATION +// +// [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: +// Each .csv file will contain a header, listing all columns' +// +// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] +// given on input followed by M target column names in the format of +// +// "<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] +// +// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>__score" where M is the number of distinct target values, +// i.e. number of distinct values in the target column of the table +// used to train the model. Subsequent lines will contain the +// respective values of successfully predicted rows, with the last, +// i.e. the target, columns having the corresponding prediction +// [scores][google.cloud.automl.v1beta1.TablesAnnotation.score]. +// For REGRESSION and FORECASTING +// +// [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: +// Each .csv file will contain a header, listing all columns' +// [display_name-s][google.cloud.automl.v1beta1.display_name] given +// on input followed by the predicted target column with name in the +// format of +// +// "predicted_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] +// +// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>" +// Subsequent lines will contain the respective values of +// successfully predicted rows, with the last, i.e. the target, +// column having the predicted target value. +// If prediction for any rows failed, then an additional +// `errors_1.csv`, `errors_2.csv`,..., `errors_N.csv` will be +// created (N depends on total number of failed rows). These files +// will have analogous format as `tables_*.csv`, but always with a +// single target column having +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// represented as a JSON string, and containing only `code` and +// `message`. +// BigQuery case: +// +// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] +// pointing to a BigQuery project must be set. In the given project a +// new dataset will be created with name +// `prediction__` +// where will be made +// BigQuery-dataset-name compatible (e.g. most special characters will +// become underscores), and timestamp will be in +// YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" format. In the dataset +// two tables will be created, `predictions`, and `errors`. +// The `predictions` table's column names will be the input columns' +// +// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] +// followed by the target column with name in the format of +// +// "predicted_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] +// +// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>" +// The input feature columns will contain the respective values of +// successfully predicted rows, with the target column having an +// ARRAY of +// +// [AnnotationPayloads][google.cloud.automl.v1beta1.AnnotationPayload], +// represented as STRUCT-s, containing +// [TablesAnnotation][google.cloud.automl.v1beta1.TablesAnnotation]. +// The `errors` table contains rows for which the prediction has +// failed, it has analogous input columns while the target column name +// is in the format of +// +// "errors_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] +// +// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>", +// and as a value has +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// represented as a STRUCT, and containing only `code` and `message`. +message BatchPredictOutputConfig { + // Required. The destination of the output. + oneof destination { + // The Google Cloud Storage location of the directory where the output is to + // be written to. + GcsDestination gcs_destination = 1; + + // The BigQuery location where the output is to be written to. + BigQueryDestination bigquery_destination = 2; + } +} + +// Output configuration for ModelExport Action. +message ModelExportOutputConfig { + // Required. The destination of the output. + oneof destination { + // The Google Cloud Storage location where the model is to be written to. + // This location may only be set for the following model formats: + // "tflite", "edgetpu_tflite", "tf_saved_model", "tf_js", "core_ml". + // + // Under the directory given as the destination a new one with name + // "model-export--", + // where timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format, + // will be created. Inside the model and any of its supporting files + // will be written. + GcsDestination gcs_destination = 1; + + // The GCR location where model image is to be pushed to. This location + // may only be set for the following model formats: + // "docker". + // + // The model image will be created under the given URI. + GcrDestination gcr_destination = 3; + } + + // The format in which the model must be exported. The available, and default, + // formats depend on the problem and model type (if given problem and type + // combination doesn't have a format listed, it means its models are not + // exportable): + // + // * For Image Classification mobile-low-latency-1, mobile-versatile-1, + // mobile-high-accuracy-1: + // "tflite" (default), "edgetpu_tflite", "tf_saved_model", "tf_js", + // "docker". + // + // * For Image Classification mobile-core-ml-low-latency-1, + // mobile-core-ml-versatile-1, mobile-core-ml-high-accuracy-1: + // "core_ml" (default). + // Formats description: + // + // * tflite - Used for Android mobile devices. + // * edgetpu_tflite - Used for [Edge TPU](https://cloud.google.com/edge-tpu/) + // devices. + // * tf_saved_model - A tensorflow model in SavedModel format. + // * tf_js - A [TensorFlow.js](https://www.tensorflow.org/js) model that can + // be used in the browser and in Node.js using JavaScript. + // * docker - Used for Docker containers. Use the params field to customize + // the container. The container is verified to work correctly on + // ubuntu 16.04 operating system. See more at + // [containers + // + // quickstart](https: + // //cloud.google.com/vision/automl/docs/containers-gcs-quickstart) + // * core_ml - Used for iOS mobile devices. + string model_format = 4; + + // Additional model-type and format specific parameters describing the + // requirements for the to be exported model files, any string must be up to + // 25000 characters long. + // + // * For `docker` format: + // `cpu_architecture` - (string) "x86_64" (default). + // `gpu_architecture` - (string) "none" (default), "nvidia". + map params = 2; +} + +// Output configuration for ExportEvaluatedExamples Action. Note that this call +// is available only for 30 days since the moment the model was evaluated. +// The output depends on the domain, as follows (note that only examples from +// the TEST set are exported): +// +// * For Tables: +// +// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] +// pointing to a BigQuery project must be set. In the given project a +// new dataset will be created with name +// +// `export_evaluated_examples__` +// where will be made BigQuery-dataset-name +// compatible (e.g. most special characters will become underscores), +// and timestamp will be in YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" +// format. In the dataset an `evaluated_examples` table will be +// created. It will have all the same columns as the +// +// [primary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_spec_id] +// of the +// [dataset][google.cloud.automl.v1beta1.Model.dataset_id] from which +// the model was created, as they were at the moment of model's +// evaluation (this includes the target column with its ground +// truth), followed by a column called "predicted_". That +// last column will contain the model's prediction result for each +// respective row, given as ARRAY of +// [AnnotationPayloads][google.cloud.automl.v1beta1.AnnotationPayload], +// represented as STRUCT-s, containing +// [TablesAnnotation][google.cloud.automl.v1beta1.TablesAnnotation]. +message ExportEvaluatedExamplesOutputConfig { + // Required. The destination of the output. + oneof destination { + // The BigQuery location where the output is to be written to. + BigQueryDestination bigquery_destination = 2; + } +} + +// The Google Cloud Storage location for the input content. +message GcsSource { + // Required. Google Cloud Storage URIs to input files, up to 2000 characters + // long. Accepted forms: + // * Full object path, e.g. gs://bucket/directory/object.csv + repeated string input_uris = 1; +} + +// The BigQuery location for the input content. +message BigQuerySource { + // Required. BigQuery URI to a table, up to 2000 characters long. + // Accepted forms: + // * BigQuery path e.g. bq://projectId.bqDatasetId.bqTableId + string input_uri = 1; +} + +// The Google Cloud Storage location where the output is to be written to. +message GcsDestination { + // Required. Google Cloud Storage URI to output directory, up to 2000 + // characters long. + // Accepted forms: + // * Prefix path: gs://bucket/directory + // The requesting user must have write permission to the bucket. + // The directory is created if it doesn't exist. + string output_uri_prefix = 1; +} + +// The BigQuery location for the output content. +message BigQueryDestination { + // Required. BigQuery URI to a project, up to 2000 characters long. + // Accepted forms: + // * BigQuery path e.g. bq://projectId + string output_uri = 1; +} + +// The GCR location where the image must be pushed to. +message GcrDestination { + // Required. Google Contained Registry URI of the new image, up to 2000 + // characters long. See + // + // https: + // //cloud.google.com/container-registry/do + // // cs/pushing-and-pulling#pushing_an_image_to_a_registry + // Accepted forms: + // * [HOSTNAME]/[PROJECT-ID]/[IMAGE] + // * [HOSTNAME]/[PROJECT-ID]/[IMAGE]:[TAG] + // + // The requesting user must have permission to push images the project. + string output_uri = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/model.proto b/google/cloud/automl_v1beta1/proto/model.proto new file mode 100644 index 00000000..2b2e8d73 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/model.proto @@ -0,0 +1,108 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/image.proto"; +import "google/cloud/automl/v1beta1/tables.proto"; +import "google/cloud/automl/v1beta1/text.proto"; +import "google/cloud/automl/v1beta1/translation.proto"; +import "google/cloud/automl/v1beta1/video.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// API proto representing a trained machine learning model. +message Model { + option (google.api.resource) = { + type: "automl.googleapis.com/Model" + pattern: "projects/{project}/locations/{location}/models/{model}" + }; + + // Deployment state of the model. + enum DeploymentState { + // Should not be used, an un-set enum has this value by default. + DEPLOYMENT_STATE_UNSPECIFIED = 0; + + // Model is deployed. + DEPLOYED = 1; + + // Model is not deployed. + UNDEPLOYED = 2; + } + + // Required. + // The model metadata that is specific to the problem type. + // Must match the metadata type of the dataset used to train the model. + oneof model_metadata { + // Metadata for translation models. + TranslationModelMetadata translation_model_metadata = 15; + + // Metadata for image classification models. + ImageClassificationModelMetadata image_classification_model_metadata = 13; + + // Metadata for text classification models. + TextClassificationModelMetadata text_classification_model_metadata = 14; + + // Metadata for image object detection models. + ImageObjectDetectionModelMetadata image_object_detection_model_metadata = 20; + + // Metadata for video classification models. + VideoClassificationModelMetadata video_classification_model_metadata = 23; + + // Metadata for video object tracking models. + VideoObjectTrackingModelMetadata video_object_tracking_model_metadata = 21; + + // Metadata for text extraction models. + TextExtractionModelMetadata text_extraction_model_metadata = 19; + + // Metadata for Tables models. + TablesModelMetadata tables_model_metadata = 24; + + // Metadata for text sentiment models. + TextSentimentModelMetadata text_sentiment_model_metadata = 22; + } + + // Output only. Resource name of the model. + // Format: `projects/{project_id}/locations/{location_id}/models/{model_id}` + string name = 1; + + // Required. The name of the model to show in the interface. The name can be + // up to 32 characters long and can consist only of ASCII Latin letters A-Z + // and a-z, underscores + // (_), and ASCII digits 0-9. It must start with a letter. + string display_name = 2; + + // Required. The resource ID of the dataset used to create the model. The dataset must + // come from the same ancestor project and location. + string dataset_id = 3; + + // Output only. Timestamp when the model training finished and can be used for prediction. + google.protobuf.Timestamp create_time = 7; + + // Output only. Timestamp when this model was last updated. + google.protobuf.Timestamp update_time = 11; + + // Output only. Deployment state of the model. A model can only serve + // prediction requests after it gets deployed. + DeploymentState deployment_state = 8; +} diff --git a/google/cloud/automl_v1beta1/proto/model_evaluation.proto b/google/cloud/automl_v1beta1/proto/model_evaluation.proto new file mode 100644 index 00000000..d5633fcd --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/model_evaluation.proto @@ -0,0 +1,116 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/cloud/automl/v1beta1/detection.proto"; +import "google/cloud/automl/v1beta1/regression.proto"; +import "google/cloud/automl/v1beta1/tables.proto"; +import "google/cloud/automl/v1beta1/text_extraction.proto"; +import "google/cloud/automl/v1beta1/text_sentiment.proto"; +import "google/cloud/automl/v1beta1/translation.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Evaluation results of a model. +message ModelEvaluation { + option (google.api.resource) = { + type: "automl.googleapis.com/ModelEvaluation" + pattern: "projects/{project}/locations/{location}/models/{model}/modelEvaluations/{model_evaluation}" + }; + + // Output only. Problem type specific evaluation metrics. + oneof metrics { + // Model evaluation metrics for image, text, video and tables + // classification. + // Tables problem is considered a classification when the target column + // is CATEGORY DataType. + ClassificationEvaluationMetrics classification_evaluation_metrics = 8; + + // Model evaluation metrics for Tables regression. + // Tables problem is considered a regression when the target column + // has FLOAT64 DataType. + RegressionEvaluationMetrics regression_evaluation_metrics = 24; + + // Model evaluation metrics for translation. + TranslationEvaluationMetrics translation_evaluation_metrics = 9; + + // Model evaluation metrics for image object detection. + ImageObjectDetectionEvaluationMetrics image_object_detection_evaluation_metrics = 12; + + // Model evaluation metrics for video object tracking. + VideoObjectTrackingEvaluationMetrics video_object_tracking_evaluation_metrics = 14; + + // Evaluation metrics for text sentiment models. + TextSentimentEvaluationMetrics text_sentiment_evaluation_metrics = 11; + + // Evaluation metrics for text extraction models. + TextExtractionEvaluationMetrics text_extraction_evaluation_metrics = 13; + } + + // Output only. Resource name of the model evaluation. + // Format: + // + // `projects/{project_id}/locations/{location_id}/models/{model_id}/modelEvaluations/{model_evaluation_id}` + string name = 1; + + // Output only. The ID of the annotation spec that the model evaluation applies to. The + // The ID is empty for the overall model evaluation. + // For Tables annotation specs in the dataset do not exist and this ID is + // always not set, but for CLASSIFICATION + // + // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] + // the + // [display_name][google.cloud.automl.v1beta1.ModelEvaluation.display_name] + // field is used. + string annotation_spec_id = 2; + + // Output only. The value of + // [display_name][google.cloud.automl.v1beta1.AnnotationSpec.display_name] at + // the moment when the model was trained. Because this field returns a value + // at model training time, for different models trained from the same dataset, + // the values may differ, since display names could had been changed between + // the two model's trainings. + // For Tables CLASSIFICATION + // + // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] + // distinct values of the target column at the moment of the model evaluation + // are populated here. + // The display_name is empty for the overall model evaluation. + string display_name = 15; + + // Output only. Timestamp when this model evaluation was created. + google.protobuf.Timestamp create_time = 5; + + // Output only. The number of examples used for model evaluation, i.e. for + // which ground truth from time of model creation is compared against the + // predicted annotations created by the model. + // For overall ModelEvaluation (i.e. with annotation_spec_id not set) this is + // the total number of all examples used for evaluation. + // Otherwise, this is the count of examples that according to the ground + // truth were annotated by the + // + // [annotation_spec_id][google.cloud.automl.v1beta1.ModelEvaluation.annotation_spec_id]. + int32 evaluated_example_count = 6; +} diff --git a/google/cloud/automl_v1beta1/proto/operations.proto b/google/cloud/automl_v1beta1/proto/operations.proto new file mode 100644 index 00000000..cce3fedc --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/operations.proto @@ -0,0 +1,189 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/io.proto"; +import "google/cloud/automl/v1beta1/model.proto"; +import "google/cloud/automl/v1beta1/model_evaluation.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; +import "google/rpc/status.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Metadata used across all long running operations returned by AutoML API. +message OperationMetadata { + // Ouptut only. Details of specific operation. Even if this field is empty, + // the presence allows to distinguish different types of operations. + oneof details { + // Details of a Delete operation. + DeleteOperationMetadata delete_details = 8; + + // Details of a DeployModel operation. + DeployModelOperationMetadata deploy_model_details = 24; + + // Details of an UndeployModel operation. + UndeployModelOperationMetadata undeploy_model_details = 25; + + // Details of CreateModel operation. + CreateModelOperationMetadata create_model_details = 10; + + // Details of ImportData operation. + ImportDataOperationMetadata import_data_details = 15; + + // Details of BatchPredict operation. + BatchPredictOperationMetadata batch_predict_details = 16; + + // Details of ExportData operation. + ExportDataOperationMetadata export_data_details = 21; + + // Details of ExportModel operation. + ExportModelOperationMetadata export_model_details = 22; + + // Details of ExportEvaluatedExamples operation. + ExportEvaluatedExamplesOperationMetadata export_evaluated_examples_details = 26; + } + + // Output only. Progress of operation. Range: [0, 100]. + // Not used currently. + int32 progress_percent = 13; + + // Output only. Partial failures encountered. + // E.g. single files that couldn't be read. + // This field should never exceed 20 entries. + // Status details field will contain standard GCP error details. + repeated google.rpc.Status partial_failures = 2; + + // Output only. Time when the operation was created. + google.protobuf.Timestamp create_time = 3; + + // Output only. Time when the operation was updated for the last time. + google.protobuf.Timestamp update_time = 4; +} + +// Details of operations that perform deletes of any entities. +message DeleteOperationMetadata { + +} + +// Details of DeployModel operation. +message DeployModelOperationMetadata { + +} + +// Details of UndeployModel operation. +message UndeployModelOperationMetadata { + +} + +// Details of CreateModel operation. +message CreateModelOperationMetadata { + +} + +// Details of ImportData operation. +message ImportDataOperationMetadata { + +} + +// Details of ExportData operation. +message ExportDataOperationMetadata { + // Further describes this export data's output. + // Supplements + // [OutputConfig][google.cloud.automl.v1beta1.OutputConfig]. + message ExportDataOutputInfo { + // The output location to which the exported data is written. + oneof output_location { + // The full path of the Google Cloud Storage directory created, into which + // the exported data is written. + string gcs_output_directory = 1; + + // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId + // format, into which the exported data is written. + string bigquery_output_dataset = 2; + } + } + + // Output only. Information further describing this export data's output. + ExportDataOutputInfo output_info = 1; +} + +// Details of BatchPredict operation. +message BatchPredictOperationMetadata { + // Further describes this batch predict's output. + // Supplements + // + // [BatchPredictOutputConfig][google.cloud.automl.v1beta1.BatchPredictOutputConfig]. + message BatchPredictOutputInfo { + // The output location into which prediction output is written. + oneof output_location { + // The full path of the Google Cloud Storage directory created, into which + // the prediction output is written. + string gcs_output_directory = 1; + + // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId + // format, into which the prediction output is written. + string bigquery_output_dataset = 2; + } + } + + // Output only. The input config that was given upon starting this + // batch predict operation. + BatchPredictInputConfig input_config = 1; + + // Output only. Information further describing this batch predict's output. + BatchPredictOutputInfo output_info = 2; +} + +// Details of ExportModel operation. +message ExportModelOperationMetadata { + // Further describes the output of model export. + // Supplements + // + // [ModelExportOutputConfig][google.cloud.automl.v1beta1.ModelExportOutputConfig]. + message ExportModelOutputInfo { + // The full path of the Google Cloud Storage directory created, into which + // the model will be exported. + string gcs_output_directory = 1; + } + + // Output only. Information further describing the output of this model + // export. + ExportModelOutputInfo output_info = 2; +} + +// Details of EvaluatedExamples operation. +message ExportEvaluatedExamplesOperationMetadata { + // Further describes the output of the evaluated examples export. + // Supplements + // + // [ExportEvaluatedExamplesOutputConfig][google.cloud.automl.v1beta1.ExportEvaluatedExamplesOutputConfig]. + message ExportEvaluatedExamplesOutputInfo { + // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId + // format, into which the output of export evaluated examples is written. + string bigquery_output_dataset = 2; + } + + // Output only. Information further describing the output of this evaluated + // examples export. + ExportEvaluatedExamplesOutputInfo output_info = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/prediction_service.proto b/google/cloud/automl_v1beta1/proto/prediction_service.proto new file mode 100644 index 00000000..0bcf685e --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/prediction_service.proto @@ -0,0 +1,268 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/annotation_payload.proto"; +import "google/cloud/automl/v1beta1/data_items.proto"; +import "google/cloud/automl/v1beta1/io.proto"; +import "google/cloud/automl/v1beta1/operations.proto"; +import "google/longrunning/operations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "PredictionServiceProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// AutoML Prediction API. +// +// On any input that is documented to expect a string parameter in +// snake_case or kebab-case, either of those cases is accepted. +service PredictionService { + option (google.api.default_host) = "automl.googleapis.com"; + option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; + + // Perform an online prediction. The prediction result will be directly + // returned in the response. + // Available for following ML problems, and their expected request payloads: + // * Image Classification - Image in .JPEG, .GIF or .PNG format, image_bytes + // up to 30MB. + // * Image Object Detection - Image in .JPEG, .GIF or .PNG format, image_bytes + // up to 30MB. + // * Text Classification - TextSnippet, content up to 60,000 characters, + // UTF-8 encoded. + // * Text Extraction - TextSnippet, content up to 30,000 characters, + // UTF-8 NFC encoded. + // * Translation - TextSnippet, content up to 25,000 characters, UTF-8 + // encoded. + // * Tables - Row, with column values matching the columns of the model, + // up to 5MB. Not available for FORECASTING + // + // [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]. + // * Text Sentiment - TextSnippet, content up 500 characters, UTF-8 + // encoded. + rpc Predict(PredictRequest) returns (PredictResponse) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:predict" + body: "*" + }; + option (google.api.method_signature) = "name,payload,params"; + } + + // Perform a batch prediction. Unlike the online [Predict][google.cloud.automl.v1beta1.PredictionService.Predict], batch + // prediction result won't be immediately available in the response. Instead, + // a long running operation object is returned. User can poll the operation + // result via [GetOperation][google.longrunning.Operations.GetOperation] + // method. Once the operation is done, [BatchPredictResult][google.cloud.automl.v1beta1.BatchPredictResult] is returned in + // the [response][google.longrunning.Operation.response] field. + // Available for following ML problems: + // * Image Classification + // * Image Object Detection + // * Video Classification + // * Video Object Tracking * Text Extraction + // * Tables + rpc BatchPredict(BatchPredictRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:batchPredict" + body: "*" + }; + option (google.api.method_signature) = "name,input_config,output_config,params"; + option (google.longrunning.operation_info) = { + response_type: "BatchPredictResult" + metadata_type: "OperationMetadata" + }; + } +} + +// Request message for [PredictionService.Predict][google.cloud.automl.v1beta1.PredictionService.Predict]. +message PredictRequest { + // Required. Name of the model requested to serve the prediction. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // Required. Payload to perform a prediction on. The payload must match the + // problem type that the model was trained to solve. + ExamplePayload payload = 2 [(google.api.field_behavior) = REQUIRED]; + + // Additional domain-specific parameters, any string must be up to 25000 + // characters long. + // + // * For Image Classification: + // + // `score_threshold` - (float) A value from 0.0 to 1.0. When the model + // makes predictions for an image, it will only produce results that have + // at least this confidence score. The default is 0.5. + // + // * For Image Object Detection: + // `score_threshold` - (float) When Model detects objects on the image, + // it will only produce bounding boxes which have at least this + // confidence score. Value in 0 to 1 range, default is 0.5. + // `max_bounding_box_count` - (int64) No more than this number of bounding + // boxes will be returned in the response. Default is 100, the + // requested value may be limited by server. + // * For Tables: + // feature_importance - (boolean) Whether feature importance + // should be populated in the returned TablesAnnotation. + // The default is false. + map params = 3; +} + +// Response message for [PredictionService.Predict][google.cloud.automl.v1beta1.PredictionService.Predict]. +message PredictResponse { + // Prediction result. + // Translation and Text Sentiment will return precisely one payload. + repeated AnnotationPayload payload = 1; + + // The preprocessed example that AutoML actually makes prediction on. + // Empty if AutoML does not preprocess the input example. + // * For Text Extraction: + // If the input is a .pdf file, the OCR'ed text will be provided in + // [document_text][google.cloud.automl.v1beta1.Document.document_text]. + ExamplePayload preprocessed_input = 3; + + // Additional domain-specific prediction response metadata. + // + // * For Image Object Detection: + // `max_bounding_box_count` - (int64) At most that many bounding boxes per + // image could have been returned. + // + // * For Text Sentiment: + // `sentiment_score` - (float, deprecated) A value between -1 and 1, + // -1 maps to least positive sentiment, while 1 maps to the most positive + // one and the higher the score, the more positive the sentiment in the + // document is. Yet these values are relative to the training data, so + // e.g. if all data was positive then -1 will be also positive (though + // the least). + // The sentiment_score shouldn't be confused with "score" or "magnitude" + // from the previous Natural Language Sentiment Analysis API. + map metadata = 2; +} + +// Request message for [PredictionService.BatchPredict][google.cloud.automl.v1beta1.PredictionService.BatchPredict]. +message BatchPredictRequest { + // Required. Name of the model requested to serve the batch prediction. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // Required. The input configuration for batch prediction. + BatchPredictInputConfig input_config = 3 [(google.api.field_behavior) = REQUIRED]; + + // Required. The Configuration specifying where output predictions should + // be written. + BatchPredictOutputConfig output_config = 4 [(google.api.field_behavior) = REQUIRED]; + + // Required. Additional domain-specific parameters for the predictions, any string must + // be up to 25000 characters long. + // + // * For Text Classification: + // + // `score_threshold` - (float) A value from 0.0 to 1.0. When the model + // makes predictions for a text snippet, it will only produce results + // that have at least this confidence score. The default is 0.5. + // + // * For Image Classification: + // + // `score_threshold` - (float) A value from 0.0 to 1.0. When the model + // makes predictions for an image, it will only produce results that + // have at least this confidence score. The default is 0.5. + // + // * For Image Object Detection: + // + // `score_threshold` - (float) When Model detects objects on the image, + // it will only produce bounding boxes which have at least this + // confidence score. Value in 0 to 1 range, default is 0.5. + // `max_bounding_box_count` - (int64) No more than this number of bounding + // boxes will be produced per image. Default is 100, the + // requested value may be limited by server. + // + // * For Video Classification : + // + // `score_threshold` - (float) A value from 0.0 to 1.0. When the model + // makes predictions for a video, it will only produce results that + // have at least this confidence score. The default is 0.5. + // `segment_classification` - (boolean) Set to true to request + // segment-level classification. AutoML Video Intelligence returns + // labels and their confidence scores for the entire segment of the + // video that user specified in the request configuration. + // The default is "true". + // `shot_classification` - (boolean) Set to true to request shot-level + // classification. AutoML Video Intelligence determines the boundaries + // for each camera shot in the entire segment of the video that user + // specified in the request configuration. AutoML Video Intelligence + // then returns labels and their confidence scores for each detected + // shot, along with the start and end time of the shot. + // WARNING: Model evaluation is not done for this classification type, + // the quality of it depends on training data, but there are no metrics + // provided to describe that quality. The default is "false". + // `1s_interval_classification` - (boolean) Set to true to request + // classification for a video at one-second intervals. AutoML Video + // Intelligence returns labels and their confidence scores for each + // second of the entire segment of the video that user specified in the + // request configuration. + // WARNING: Model evaluation is not done for this classification + // type, the quality of it depends on training data, but there are no + // metrics provided to describe that quality. The default is + // "false". + // + // * For Tables: + // + // feature_importance - (boolean) Whether feature importance + // should be populated in the returned TablesAnnotations. The + // default is false. + // + // * For Video Object Tracking: + // + // `score_threshold` - (float) When Model detects objects on video frames, + // it will only produce bounding boxes which have at least this + // confidence score. Value in 0 to 1 range, default is 0.5. + // `max_bounding_box_count` - (int64) No more than this number of bounding + // boxes will be returned per frame. Default is 100, the requested + // value may be limited by server. + // `min_bounding_box_size` - (float) Only bounding boxes with shortest edge + // at least that long as a relative value of video frame size will be + // returned. Value in 0 to 1 range. Default is 0. + map params = 5 [(google.api.field_behavior) = REQUIRED]; +} + +// Result of the Batch Predict. This message is returned in +// [response][google.longrunning.Operation.response] of the operation returned +// by the [PredictionService.BatchPredict][google.cloud.automl.v1beta1.PredictionService.BatchPredict]. +message BatchPredictResult { + // Additional domain-specific prediction response metadata. + // + // * For Image Object Detection: + // `max_bounding_box_count` - (int64) At most that many bounding boxes per + // image could have been returned. + // + // * For Video Object Tracking: + // `max_bounding_box_count` - (int64) At most that many bounding boxes per + // frame could have been returned. + map metadata = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/ranges.proto b/google/cloud/automl_v1beta1/proto/ranges.proto new file mode 100644 index 00000000..89572bb0 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/ranges.proto @@ -0,0 +1,35 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "RangesProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A range between two double numbers. +message DoubleRange { + // Start of the range, inclusive. + double start = 1; + + // End of the range, exclusive. + double end = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/regression.proto b/google/cloud/automl_v1beta1/proto/regression.proto new file mode 100644 index 00000000..1286d3d8 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/regression.proto @@ -0,0 +1,44 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_outer_classname = "RegressionProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Metrics for regression problems. +message RegressionEvaluationMetrics { + // Output only. Root Mean Squared Error (RMSE). + float root_mean_squared_error = 1; + + // Output only. Mean Absolute Error (MAE). + float mean_absolute_error = 2; + + // Output only. Mean absolute percentage error. Only set if all ground truth + // values are are positive. + float mean_absolute_percentage_error = 3; + + // Output only. R squared. + float r_squared = 4; + + // Output only. Root mean squared log error. + float root_mean_squared_log_error = 5; +} diff --git a/google/cloud/automl_v1beta1/proto/service.proto b/google/cloud/automl_v1beta1/proto/service.proto new file mode 100644 index 00000000..a421ece1 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/service.proto @@ -0,0 +1,800 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/annotation_payload.proto"; +import "google/cloud/automl/v1beta1/annotation_spec.proto"; +import "google/cloud/automl/v1beta1/column_spec.proto"; +import "google/cloud/automl/v1beta1/dataset.proto"; +import "google/cloud/automl/v1beta1/image.proto"; +import "google/cloud/automl/v1beta1/io.proto"; +import "google/cloud/automl/v1beta1/model.proto"; +import "google/cloud/automl/v1beta1/model_evaluation.proto"; +import "google/cloud/automl/v1beta1/operations.proto"; +import "google/cloud/automl/v1beta1/table_spec.proto"; +import "google/longrunning/operations.proto"; +import "google/protobuf/field_mask.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "AutoMlProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// AutoML Server API. +// +// The resource names are assigned by the server. +// The server never reuses names that it has created after the resources with +// those names are deleted. +// +// An ID of a resource is the last element of the item's resource name. For +// `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}`, then +// the id for the item is `{dataset_id}`. +// +// Currently the only supported `location_id` is "us-central1". +// +// On any input that is documented to expect a string parameter in +// snake_case or kebab-case, either of those cases is accepted. +service AutoMl { + option (google.api.default_host) = "automl.googleapis.com"; + option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; + + // Creates a dataset. + rpc CreateDataset(CreateDatasetRequest) returns (Dataset) { + option (google.api.http) = { + post: "/v1beta1/{parent=projects/*/locations/*}/datasets" + body: "dataset" + }; + option (google.api.method_signature) = "parent,dataset"; + } + + // Gets a dataset. + rpc GetDataset(GetDatasetRequest) returns (Dataset) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/datasets/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists datasets in a project. + rpc ListDatasets(ListDatasetsRequest) returns (ListDatasetsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*}/datasets" + }; + option (google.api.method_signature) = "parent"; + } + + // Updates a dataset. + rpc UpdateDataset(UpdateDatasetRequest) returns (Dataset) { + option (google.api.http) = { + patch: "/v1beta1/{dataset.name=projects/*/locations/*/datasets/*}" + body: "dataset" + }; + option (google.api.method_signature) = "dataset"; + } + + // Deletes a dataset and all of its contents. + // Returns empty response in the + // [response][google.longrunning.Operation.response] field when it completes, + // and `delete_details` in the + // [metadata][google.longrunning.Operation.metadata] field. + rpc DeleteDataset(DeleteDatasetRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + delete: "/v1beta1/{name=projects/*/locations/*/datasets/*}" + }; + option (google.api.method_signature) = "name"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Imports data into a dataset. + // For Tables this method can only be called on an empty Dataset. + // + // For Tables: + // * A + // [schema_inference_version][google.cloud.automl.v1beta1.InputConfig.params] + // parameter must be explicitly set. + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc ImportData(ImportDataRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/datasets/*}:importData" + body: "*" + }; + option (google.api.method_signature) = "name,input_config"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Exports dataset's data to the provided output location. + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc ExportData(ExportDataRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/datasets/*}:exportData" + body: "*" + }; + option (google.api.method_signature) = "name,output_config"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Gets an annotation spec. + rpc GetAnnotationSpec(GetAnnotationSpecRequest) returns (AnnotationSpec) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/datasets/*/annotationSpecs/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Gets a table spec. + rpc GetTableSpec(GetTableSpecRequest) returns (TableSpec) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/datasets/*/tableSpecs/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists table specs in a dataset. + rpc ListTableSpecs(ListTableSpecsRequest) returns (ListTableSpecsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*/datasets/*}/tableSpecs" + }; + option (google.api.method_signature) = "parent"; + } + + // Updates a table spec. + rpc UpdateTableSpec(UpdateTableSpecRequest) returns (TableSpec) { + option (google.api.http) = { + patch: "/v1beta1/{table_spec.name=projects/*/locations/*/datasets/*/tableSpecs/*}" + body: "table_spec" + }; + option (google.api.method_signature) = "table_spec"; + } + + // Gets a column spec. + rpc GetColumnSpec(GetColumnSpecRequest) returns (ColumnSpec) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/datasets/*/tableSpecs/*/columnSpecs/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists column specs in a table spec. + rpc ListColumnSpecs(ListColumnSpecsRequest) returns (ListColumnSpecsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*/datasets/*/tableSpecs/*}/columnSpecs" + }; + option (google.api.method_signature) = "parent"; + } + + // Updates a column spec. + rpc UpdateColumnSpec(UpdateColumnSpecRequest) returns (ColumnSpec) { + option (google.api.http) = { + patch: "/v1beta1/{column_spec.name=projects/*/locations/*/datasets/*/tableSpecs/*/columnSpecs/*}" + body: "column_spec" + }; + option (google.api.method_signature) = "column_spec"; + } + + // Creates a model. + // Returns a Model in the [response][google.longrunning.Operation.response] + // field when it completes. + // When you create a model, several model evaluations are created for it: + // a global evaluation, and one evaluation for each annotation spec. + rpc CreateModel(CreateModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{parent=projects/*/locations/*}/models" + body: "model" + }; + option (google.api.method_signature) = "parent,model"; + option (google.longrunning.operation_info) = { + response_type: "Model" + metadata_type: "OperationMetadata" + }; + } + + // Gets a model. + rpc GetModel(GetModelRequest) returns (Model) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/models/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists models. + rpc ListModels(ListModelsRequest) returns (ListModelsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*}/models" + }; + option (google.api.method_signature) = "parent"; + } + + // Deletes a model. + // Returns `google.protobuf.Empty` in the + // [response][google.longrunning.Operation.response] field when it completes, + // and `delete_details` in the + // [metadata][google.longrunning.Operation.metadata] field. + rpc DeleteModel(DeleteModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + delete: "/v1beta1/{name=projects/*/locations/*/models/*}" + }; + option (google.api.method_signature) = "name"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Deploys a model. If a model is already deployed, deploying it with the + // same parameters has no effect. Deploying with different parametrs + // (as e.g. changing + // + // [node_number][google.cloud.automl.v1beta1.ImageObjectDetectionModelDeploymentMetadata.node_number]) + // will reset the deployment state without pausing the model's availability. + // + // Only applicable for Text Classification, Image Object Detection , Tables, and Image Segmentation; all other domains manage + // deployment automatically. + // + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc DeployModel(DeployModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:deploy" + body: "*" + }; + option (google.api.method_signature) = "name"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Undeploys a model. If the model is not deployed this method has no effect. + // + // Only applicable for Text Classification, Image Object Detection and Tables; + // all other domains manage deployment automatically. + // + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc UndeployModel(UndeployModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:undeploy" + body: "*" + }; + option (google.api.method_signature) = "name"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Exports a trained, "export-able", model to a user specified Google Cloud + // Storage location. A model is considered export-able if and only if it has + // an export format defined for it in + // + // [ModelExportOutputConfig][google.cloud.automl.v1beta1.ModelExportOutputConfig]. + // + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc ExportModel(ExportModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:export" + body: "*" + }; + option (google.api.method_signature) = "name,output_config"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Exports examples on which the model was evaluated (i.e. which were in the + // TEST set of the dataset the model was created from), together with their + // ground truth annotations and the annotations created (predicted) by the + // model. + // The examples, ground truth and predictions are exported in the state + // they were at the moment the model was evaluated. + // + // This export is available only for 30 days since the model evaluation is + // created. + // + // Currently only available for Tables. + // + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc ExportEvaluatedExamples(ExportEvaluatedExamplesRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:exportEvaluatedExamples" + body: "*" + }; + option (google.api.method_signature) = "name,output_config"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Gets a model evaluation. + rpc GetModelEvaluation(GetModelEvaluationRequest) returns (ModelEvaluation) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/models/*/modelEvaluations/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists model evaluations. + rpc ListModelEvaluations(ListModelEvaluationsRequest) returns (ListModelEvaluationsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*/models/*}/modelEvaluations" + }; + option (google.api.method_signature) = "parent"; + } +} + +// Request message for [AutoMl.CreateDataset][google.cloud.automl.v1beta1.AutoMl.CreateDataset]. +message CreateDatasetRequest { + // Required. The resource name of the project to create the dataset for. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "locations.googleapis.com/Location" + } + ]; + + // Required. The dataset to create. + Dataset dataset = 2 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.GetDataset][google.cloud.automl.v1beta1.AutoMl.GetDataset]. +message GetDatasetRequest { + // Required. The resource name of the dataset to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; +} + +// Request message for [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets]. +message ListDatasetsRequest { + // Required. The resource name of the project from which to list datasets. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "locations.googleapis.com/Location" + } + ]; + + // An expression for filtering the results of the request. + // + // * `dataset_metadata` - for existence of the case (e.g. + // image_classification_dataset_metadata:*). Some examples of using the filter are: + // + // * `translation_dataset_metadata:*` --> The dataset has + // translation_dataset_metadata. + string filter = 3; + + // Requested page size. Server may return fewer results than requested. + // If unspecified, server will pick a default size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return + // Typically obtained via + // [ListDatasetsResponse.next_page_token][google.cloud.automl.v1beta1.ListDatasetsResponse.next_page_token] of the previous + // [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets]. +message ListDatasetsResponse { + // The datasets read. + repeated Dataset datasets = 1; + + // A token to retrieve next page of results. + // Pass to [ListDatasetsRequest.page_token][google.cloud.automl.v1beta1.ListDatasetsRequest.page_token] to obtain that page. + string next_page_token = 2; +} + +// Request message for [AutoMl.UpdateDataset][google.cloud.automl.v1beta1.AutoMl.UpdateDataset] +message UpdateDatasetRequest { + // Required. The dataset which replaces the resource on the server. + Dataset dataset = 1 [(google.api.field_behavior) = REQUIRED]; + + // The update mask applies to the resource. + google.protobuf.FieldMask update_mask = 2; +} + +// Request message for [AutoMl.DeleteDataset][google.cloud.automl.v1beta1.AutoMl.DeleteDataset]. +message DeleteDatasetRequest { + // Required. The resource name of the dataset to delete. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; +} + +// Request message for [AutoMl.ImportData][google.cloud.automl.v1beta1.AutoMl.ImportData]. +message ImportDataRequest { + // Required. Dataset name. Dataset must already exist. All imported + // annotations and examples will be added. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; + + // Required. The desired input location and its domain specific semantics, + // if any. + InputConfig input_config = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.ExportData][google.cloud.automl.v1beta1.AutoMl.ExportData]. +message ExportDataRequest { + // Required. The resource name of the dataset. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; + + // Required. The desired output location. + OutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.GetAnnotationSpec][google.cloud.automl.v1beta1.AutoMl.GetAnnotationSpec]. +message GetAnnotationSpecRequest { + // Required. The resource name of the annotation spec to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/AnnotationSpec" + } + ]; +} + +// Request message for [AutoMl.GetTableSpec][google.cloud.automl.v1beta1.AutoMl.GetTableSpec]. +message GetTableSpecRequest { + // Required. The resource name of the table spec to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/TableSpec" + } + ]; + + // Mask specifying which fields to read. + google.protobuf.FieldMask field_mask = 2; +} + +// Request message for [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs]. +message ListTableSpecsRequest { + // Required. The resource name of the dataset to list table specs from. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; + + // Mask specifying which fields to read. + google.protobuf.FieldMask field_mask = 2; + + // Filter expression, see go/filtering. + string filter = 3; + + // Requested page size. The server can return fewer results than requested. + // If unspecified, the server will pick a default size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return. + // Typically obtained from the + // [ListTableSpecsResponse.next_page_token][google.cloud.automl.v1beta1.ListTableSpecsResponse.next_page_token] field of the previous + // [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs]. +message ListTableSpecsResponse { + // The table specs read. + repeated TableSpec table_specs = 1; + + // A token to retrieve next page of results. + // Pass to [ListTableSpecsRequest.page_token][google.cloud.automl.v1beta1.ListTableSpecsRequest.page_token] to obtain that page. + string next_page_token = 2; +} + +// Request message for [AutoMl.UpdateTableSpec][google.cloud.automl.v1beta1.AutoMl.UpdateTableSpec] +message UpdateTableSpecRequest { + // Required. The table spec which replaces the resource on the server. + TableSpec table_spec = 1 [(google.api.field_behavior) = REQUIRED]; + + // The update mask applies to the resource. + google.protobuf.FieldMask update_mask = 2; +} + +// Request message for [AutoMl.GetColumnSpec][google.cloud.automl.v1beta1.AutoMl.GetColumnSpec]. +message GetColumnSpecRequest { + // Required. The resource name of the column spec to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/ColumnSpec" + } + ]; + + // Mask specifying which fields to read. + google.protobuf.FieldMask field_mask = 2; +} + +// Request message for [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs]. +message ListColumnSpecsRequest { + // Required. The resource name of the table spec to list column specs from. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/TableSpec" + } + ]; + + // Mask specifying which fields to read. + google.protobuf.FieldMask field_mask = 2; + + // Filter expression, see go/filtering. + string filter = 3; + + // Requested page size. The server can return fewer results than requested. + // If unspecified, the server will pick a default size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return. + // Typically obtained from the + // [ListColumnSpecsResponse.next_page_token][google.cloud.automl.v1beta1.ListColumnSpecsResponse.next_page_token] field of the previous + // [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs]. +message ListColumnSpecsResponse { + // The column specs read. + repeated ColumnSpec column_specs = 1; + + // A token to retrieve next page of results. + // Pass to [ListColumnSpecsRequest.page_token][google.cloud.automl.v1beta1.ListColumnSpecsRequest.page_token] to obtain that page. + string next_page_token = 2; +} + +// Request message for [AutoMl.UpdateColumnSpec][google.cloud.automl.v1beta1.AutoMl.UpdateColumnSpec] +message UpdateColumnSpecRequest { + // Required. The column spec which replaces the resource on the server. + ColumnSpec column_spec = 1 [(google.api.field_behavior) = REQUIRED]; + + // The update mask applies to the resource. + google.protobuf.FieldMask update_mask = 2; +} + +// Request message for [AutoMl.CreateModel][google.cloud.automl.v1beta1.AutoMl.CreateModel]. +message CreateModelRequest { + // Required. Resource name of the parent project where the model is being created. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "locations.googleapis.com/Location" + } + ]; + + // Required. The model to create. + Model model = 4 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.GetModel][google.cloud.automl.v1beta1.AutoMl.GetModel]. +message GetModelRequest { + // Required. Resource name of the model. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; +} + +// Request message for [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels]. +message ListModelsRequest { + // Required. Resource name of the project, from which to list the models. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "locations.googleapis.com/Location" + } + ]; + + // An expression for filtering the results of the request. + // + // * `model_metadata` - for existence of the case (e.g. + // video_classification_model_metadata:*). + // * `dataset_id` - for = or !=. Some examples of using the filter are: + // + // * `image_classification_model_metadata:*` --> The model has + // image_classification_model_metadata. + // * `dataset_id=5` --> The model was created from a dataset with ID 5. + string filter = 3; + + // Requested page size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return + // Typically obtained via + // [ListModelsResponse.next_page_token][google.cloud.automl.v1beta1.ListModelsResponse.next_page_token] of the previous + // [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels]. +message ListModelsResponse { + // List of models in the requested page. + repeated Model model = 1; + + // A token to retrieve next page of results. + // Pass to [ListModelsRequest.page_token][google.cloud.automl.v1beta1.ListModelsRequest.page_token] to obtain that page. + string next_page_token = 2; +} + +// Request message for [AutoMl.DeleteModel][google.cloud.automl.v1beta1.AutoMl.DeleteModel]. +message DeleteModelRequest { + // Required. Resource name of the model being deleted. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; +} + +// Request message for [AutoMl.DeployModel][google.cloud.automl.v1beta1.AutoMl.DeployModel]. +message DeployModelRequest { + // The per-domain specific deployment parameters. + oneof model_deployment_metadata { + // Model deployment metadata specific to Image Object Detection. + ImageObjectDetectionModelDeploymentMetadata image_object_detection_model_deployment_metadata = 2; + + // Model deployment metadata specific to Image Classification. + ImageClassificationModelDeploymentMetadata image_classification_model_deployment_metadata = 4; + } + + // Required. Resource name of the model to deploy. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; +} + +// Request message for [AutoMl.UndeployModel][google.cloud.automl.v1beta1.AutoMl.UndeployModel]. +message UndeployModelRequest { + // Required. Resource name of the model to undeploy. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; +} + +// Request message for [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]. +// Models need to be enabled for exporting, otherwise an error code will be +// returned. +message ExportModelRequest { + // Required. The resource name of the model to export. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // Required. The desired output location and configuration. + ModelExportOutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.ExportEvaluatedExamples][google.cloud.automl.v1beta1.AutoMl.ExportEvaluatedExamples]. +message ExportEvaluatedExamplesRequest { + // Required. The resource name of the model whose evaluated examples are to + // be exported. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // Required. The desired output location and configuration. + ExportEvaluatedExamplesOutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.GetModelEvaluation][google.cloud.automl.v1beta1.AutoMl.GetModelEvaluation]. +message GetModelEvaluationRequest { + // Required. Resource name for the model evaluation. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/ModelEvaluation" + } + ]; +} + +// Request message for [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations]. +message ListModelEvaluationsRequest { + // Required. Resource name of the model to list the model evaluations for. + // If modelId is set as "-", this will list model evaluations from across all + // models of the parent location. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // An expression for filtering the results of the request. + // + // * `annotation_spec_id` - for =, != or existence. See example below for + // the last. + // + // Some examples of using the filter are: + // + // * `annotation_spec_id!=4` --> The model evaluation was done for + // annotation spec with ID different than 4. + // * `NOT annotation_spec_id:*` --> The model evaluation was done for + // aggregate of all annotation specs. + string filter = 3; + + // Requested page size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return. + // Typically obtained via + // [ListModelEvaluationsResponse.next_page_token][google.cloud.automl.v1beta1.ListModelEvaluationsResponse.next_page_token] of the previous + // [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations]. +message ListModelEvaluationsResponse { + // List of model evaluations in the requested page. + repeated ModelEvaluation model_evaluation = 1; + + // A token to retrieve next page of results. + // Pass to the [ListModelEvaluationsRequest.page_token][google.cloud.automl.v1beta1.ListModelEvaluationsRequest.page_token] field of a new + // [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations] request to obtain that page. + string next_page_token = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/table_spec.proto b/google/cloud/automl_v1beta1/proto/table_spec.proto new file mode 100644 index 00000000..bc3fc744 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/table_spec.proto @@ -0,0 +1,78 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/io.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A specification of a relational table. +// The table's schema is represented via its child column specs. It is +// pre-populated as part of ImportData by schema inference algorithm, the +// version of which is a required parameter of ImportData InputConfig. +// Note: While working with a table, at times the schema may be +// inconsistent with the data in the table (e.g. string in a FLOAT64 column). +// The consistency validation is done upon creation of a model. +// Used by: +// * Tables +message TableSpec { + option (google.api.resource) = { + type: "automl.googleapis.com/TableSpec" + pattern: "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}" + }; + + // Output only. The resource name of the table spec. + // Form: + // + // `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/tableSpecs/{table_spec_id}` + string name = 1; + + // column_spec_id of the time column. Only used if the parent dataset's + // ml_use_column_spec_id is not set. Used to split rows into TRAIN, VALIDATE + // and TEST sets such that oldest rows go to TRAIN set, newest to TEST, and + // those in between to VALIDATE. + // Required type: TIMESTAMP. + // If both this column and ml_use_column are not set, then ML use of all rows + // will be assigned by AutoML. NOTE: Updates of this field will instantly + // affect any other users concurrently working with the dataset. + string time_column_spec_id = 2; + + // Output only. The number of rows (i.e. examples) in the table. + int64 row_count = 3; + + // Output only. The number of valid rows (i.e. without values that don't match + // DataType-s of their columns). + int64 valid_row_count = 4; + + // Output only. The number of columns of the table. That is, the number of + // child ColumnSpec-s. + int64 column_count = 7; + + // Output only. Input configs via which data currently residing in the table + // had been imported. + repeated InputConfig input_configs = 5; + + // Used to perform consistent read-modify-write updates. If not set, a blind + // "overwrite" update happens. + string etag = 6; +} diff --git a/google/cloud/automl_v1beta1/proto/tables.proto b/google/cloud/automl_v1beta1/proto/tables.proto new file mode 100644 index 00000000..5327f5e7 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/tables.proto @@ -0,0 +1,292 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/cloud/automl/v1beta1/column_spec.proto"; +import "google/cloud/automl/v1beta1/data_items.proto"; +import "google/cloud/automl/v1beta1/data_stats.proto"; +import "google/cloud/automl/v1beta1/ranges.proto"; +import "google/cloud/automl/v1beta1/regression.proto"; +import "google/cloud/automl/v1beta1/temporal.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Metadata for a dataset used for AutoML Tables. +message TablesDatasetMetadata { + // Output only. The table_spec_id of the primary table of this dataset. + string primary_table_spec_id = 1; + + // column_spec_id of the primary table's column that should be used as the + // training & prediction target. + // This column must be non-nullable and have one of following data types + // (otherwise model creation will error): + // + // * CATEGORY + // + // * FLOAT64 + // + // If the type is CATEGORY , only up to + // 100 unique values may exist in that column across all rows. + // + // NOTE: Updates of this field will instantly affect any other users + // concurrently working with the dataset. + string target_column_spec_id = 2; + + // column_spec_id of the primary table's column that should be used as the + // weight column, i.e. the higher the value the more important the row will be + // during model training. + // Required type: FLOAT64. + // Allowed values: 0 to 10000, inclusive on both ends; 0 means the row is + // ignored for training. + // If not set all rows are assumed to have equal weight of 1. + // NOTE: Updates of this field will instantly affect any other users + // concurrently working with the dataset. + string weight_column_spec_id = 3; + + // column_spec_id of the primary table column which specifies a possible ML + // use of the row, i.e. the column will be used to split the rows into TRAIN, + // VALIDATE and TEST sets. + // Required type: STRING. + // This column, if set, must either have all of `TRAIN`, `VALIDATE`, `TEST` + // among its values, or only have `TEST`, `UNASSIGNED` values. In the latter + // case the rows with `UNASSIGNED` value will be assigned by AutoML. Note + // that if a given ml use distribution makes it impossible to create a "good" + // model, that call will error describing the issue. + // If both this column_spec_id and primary table's time_column_spec_id are not + // set, then all rows are treated as `UNASSIGNED`. + // NOTE: Updates of this field will instantly affect any other users + // concurrently working with the dataset. + string ml_use_column_spec_id = 4; + + // Output only. Correlations between + // + // [TablesDatasetMetadata.target_column_spec_id][google.cloud.automl.v1beta1.TablesDatasetMetadata.target_column_spec_id], + // and other columns of the + // + // [TablesDatasetMetadataprimary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_spec_id]. + // Only set if the target column is set. Mapping from other column spec id to + // its CorrelationStats with the target column. + // This field may be stale, see the stats_update_time field for + // for the timestamp at which these stats were last updated. + map target_column_correlations = 6; + + // Output only. The most recent timestamp when target_column_correlations + // field and all descendant ColumnSpec.data_stats and + // ColumnSpec.top_correlated_columns fields were last (re-)generated. Any + // changes that happened to the dataset afterwards are not reflected in these + // fields values. The regeneration happens in the background on a best effort + // basis. + google.protobuf.Timestamp stats_update_time = 7; +} + +// Model metadata specific to AutoML Tables. +message TablesModelMetadata { + // Additional optimization objective configuration. Required for + // `MAXIMIZE_PRECISION_AT_RECALL` and `MAXIMIZE_RECALL_AT_PRECISION`, + // otherwise unused. + oneof additional_optimization_objective_config { + // Required when optimization_objective is "MAXIMIZE_PRECISION_AT_RECALL". + // Must be between 0 and 1, inclusive. + float optimization_objective_recall_value = 17; + + // Required when optimization_objective is "MAXIMIZE_RECALL_AT_PRECISION". + // Must be between 0 and 1, inclusive. + float optimization_objective_precision_value = 18; + } + + // Column spec of the dataset's primary table's column the model is + // predicting. Snapshotted when model creation started. + // Only 3 fields are used: + // name - May be set on CreateModel, if it's not then the ColumnSpec + // corresponding to the current target_column_spec_id of the dataset + // the model is trained from is used. + // If neither is set, CreateModel will error. + // display_name - Output only. + // data_type - Output only. + ColumnSpec target_column_spec = 2; + + // Column specs of the dataset's primary table's columns, on which + // the model is trained and which are used as the input for predictions. + // The + // + // [target_column][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] + // as well as, according to dataset's state upon model creation, + // + // [weight_column][google.cloud.automl.v1beta1.TablesDatasetMetadata.weight_column_spec_id], + // and + // + // [ml_use_column][google.cloud.automl.v1beta1.TablesDatasetMetadata.ml_use_column_spec_id] + // must never be included here. + // + // Only 3 fields are used: + // + // * name - May be set on CreateModel, if set only the columns specified are + // used, otherwise all primary table's columns (except the ones listed + // above) are used for the training and prediction input. + // + // * display_name - Output only. + // + // * data_type - Output only. + repeated ColumnSpec input_feature_column_specs = 3; + + // Objective function the model is optimizing towards. The training process + // creates a model that maximizes/minimizes the value of the objective + // function over the validation set. + // + // The supported optimization objectives depend on the prediction type. + // If the field is not set, a default objective function is used. + // + // CLASSIFICATION_BINARY: + // "MAXIMIZE_AU_ROC" (default) - Maximize the area under the receiver + // operating characteristic (ROC) curve. + // "MINIMIZE_LOG_LOSS" - Minimize log loss. + // "MAXIMIZE_AU_PRC" - Maximize the area under the precision-recall curve. + // "MAXIMIZE_PRECISION_AT_RECALL" - Maximize precision for a specified + // recall value. + // "MAXIMIZE_RECALL_AT_PRECISION" - Maximize recall for a specified + // precision value. + // + // CLASSIFICATION_MULTI_CLASS : + // "MINIMIZE_LOG_LOSS" (default) - Minimize log loss. + // + // + // REGRESSION: + // "MINIMIZE_RMSE" (default) - Minimize root-mean-squared error (RMSE). + // "MINIMIZE_MAE" - Minimize mean-absolute error (MAE). + // "MINIMIZE_RMSLE" - Minimize root-mean-squared log error (RMSLE). + string optimization_objective = 4; + + // Output only. Auxiliary information for each of the + // input_feature_column_specs with respect to this particular model. + repeated TablesModelColumnInfo tables_model_column_info = 5; + + // Required. The train budget of creating this model, expressed in milli node + // hours i.e. 1,000 value in this field means 1 node hour. + // + // The training cost of the model will not exceed this budget. The final cost + // will be attempted to be close to the budget, though may end up being (even) + // noticeably smaller - at the backend's discretion. This especially may + // happen when further model training ceases to provide any improvements. + // + // If the budget is set to a value known to be insufficient to train a + // model for the given dataset, the training won't be attempted and + // will error. + // + // The train budget must be between 1,000 and 72,000 milli node hours, + // inclusive. + int64 train_budget_milli_node_hours = 6; + + // Output only. The actual training cost of the model, expressed in milli + // node hours, i.e. 1,000 value in this field means 1 node hour. Guaranteed + // to not exceed the train budget. + int64 train_cost_milli_node_hours = 7; + + // Use the entire training budget. This disables the early stopping feature. + // By default, the early stopping feature is enabled, which means that AutoML + // Tables might stop training before the entire training budget has been used. + bool disable_early_stopping = 12; +} + +// Contains annotation details specific to Tables. +message TablesAnnotation { + // Output only. A confidence estimate between 0.0 and 1.0, inclusive. A higher + // value means greater confidence in the returned value. + // For + // + // [target_column_spec][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] + // of FLOAT64 data type the score is not populated. + float score = 1; + + // Output only. Only populated when + // + // [target_column_spec][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] + // has FLOAT64 data type. An interval in which the exactly correct target + // value has 95% chance to be in. + DoubleRange prediction_interval = 4; + + // The predicted value of the row's + // + // [target_column][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec]. + // The value depends on the column's DataType: + // + // * CATEGORY - the predicted (with the above confidence `score`) CATEGORY + // value. + // + // * FLOAT64 - the predicted (with above `prediction_interval`) FLOAT64 value. + google.protobuf.Value value = 2; + + // Output only. Auxiliary information for each of the model's + // + // [input_feature_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] + // with respect to this particular prediction. + // If no other fields than + // + // [column_spec_name][google.cloud.automl.v1beta1.TablesModelColumnInfo.column_spec_name] + // and + // + // [column_display_name][google.cloud.automl.v1beta1.TablesModelColumnInfo.column_display_name] + // would be populated, then this whole field is not. + repeated TablesModelColumnInfo tables_model_column_info = 3; + + // Output only. Stores the prediction score for the baseline example, which + // is defined as the example with all values set to their baseline values. + // This is used as part of the Sampled Shapley explanation of the model's + // prediction. This field is populated only when feature importance is + // requested. For regression models, this holds the baseline prediction for + // the baseline example. For classification models, this holds the baseline + // prediction for the baseline example for the argmax class. + float baseline_score = 5; +} + +// An information specific to given column and Tables Model, in context +// of the Model and the predictions created by it. +message TablesModelColumnInfo { + // Output only. The name of the ColumnSpec describing the column. Not + // populated when this proto is outputted to BigQuery. + string column_spec_name = 1; + + // Output only. The display name of the column (same as the display_name of + // its ColumnSpec). + string column_display_name = 2; + + // Output only. When given as part of a Model (always populated): + // Measurement of how much model predictions correctness on the TEST data + // depend on values in this column. A value between 0 and 1, higher means + // higher influence. These values are normalized - for all input feature + // columns of a given model they add to 1. + // + // When given back by Predict (populated iff + // [feature_importance + // param][google.cloud.automl.v1beta1.PredictRequest.params] is set) or Batch + // Predict (populated iff + // [feature_importance][google.cloud.automl.v1beta1.PredictRequest.params] + // param is set): + // Measurement of how impactful for the prediction returned for the given row + // the value in this column was. Specifically, the feature importance + // specifies the marginal contribution that the feature made to the prediction + // score compared to the baseline score. These values are computed using the + // Sampled Shapley method. + float feature_importance = 3; +} diff --git a/google/cloud/automl_v1beta1/proto/temporal.proto b/google/cloud/automl_v1beta1/proto/temporal.proto new file mode 100644 index 00000000..76db8887 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/temporal.proto @@ -0,0 +1,37 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/protobuf/duration.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A time period inside of an example that has a time dimension (e.g. video). +message TimeSegment { + // Start of the time segment (inclusive), represented as the duration since + // the example start. + google.protobuf.Duration start_time_offset = 1; + + // End of the time segment (exclusive), represented as the duration since the + // example start. + google.protobuf.Duration end_time_offset = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/text.proto b/google/cloud/automl_v1beta1/proto/text.proto new file mode 100644 index 00000000..f6f33185 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/text.proto @@ -0,0 +1,65 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "TextProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Dataset metadata for classification. +message TextClassificationDatasetMetadata { + // Required. Type of the classification problem. + ClassificationType classification_type = 1; +} + +// Model metadata that is specific to text classification. +message TextClassificationModelMetadata { + // Output only. Classification type of the dataset used to train this model. + ClassificationType classification_type = 3; +} + +// Dataset metadata that is specific to text extraction +message TextExtractionDatasetMetadata { + +} + +// Model metadata that is specific to text extraction. +message TextExtractionModelMetadata { + +} + +// Dataset metadata for text sentiment. +message TextSentimentDatasetMetadata { + // Required. A sentiment is expressed as an integer ordinal, where higher value + // means a more positive sentiment. The range of sentiments that will be used + // is between 0 and sentiment_max (inclusive on both ends), and all the values + // in the range must be represented in the dataset before a model can be + // created. + // sentiment_max value must be between 1 and 10 (inclusive). + int32 sentiment_max = 1; +} + +// Model metadata that is specific to text sentiment. +message TextSentimentModelMetadata { + +} diff --git a/google/cloud/automl_v1beta1/proto/text_extraction.proto b/google/cloud/automl_v1beta1/proto/text_extraction.proto new file mode 100644 index 00000000..cfb0e0b3 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/text_extraction.proto @@ -0,0 +1,68 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/text_segment.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Annotation for identifying spans of text. +message TextExtractionAnnotation { + // Required. Text extraction annotations can either be a text segment or a + // text relation. + oneof annotation { + // An entity annotation will set this, which is the part of the original + // text to which the annotation pertains. + TextSegment text_segment = 3; + } + + // Output only. A confidence estimate between 0.0 and 1.0. A higher value + // means greater confidence in correctness of the annotation. + float score = 1; +} + +// Model evaluation metrics for text extraction problems. +message TextExtractionEvaluationMetrics { + // Metrics for a single confidence threshold. + message ConfidenceMetricsEntry { + // Output only. The confidence threshold value used to compute the metrics. + // Only annotations with score of at least this threshold are considered to + // be ones the model would return. + float confidence_threshold = 1; + + // Output only. Recall under the given confidence threshold. + float recall = 3; + + // Output only. Precision under the given confidence threshold. + float precision = 4; + + // Output only. The harmonic mean of recall and precision. + float f1_score = 5; + } + + // Output only. The Area under precision recall curve metric. + float au_prc = 1; + + // Output only. Metrics that have confidence thresholds. + // Precision-recall curve can be derived from it. + repeated ConfidenceMetricsEntry confidence_metrics_entries = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/text_segment.proto b/google/cloud/automl_v1beta1/proto/text_segment.proto new file mode 100644 index 00000000..94b17d93 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/text_segment.proto @@ -0,0 +1,41 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "TextSegmentProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A contiguous part of a text (string), assuming it has an UTF-8 NFC encoding. +message TextSegment { + // Output only. The content of the TextSegment. + string content = 3; + + // Required. Zero-based character index of the first character of the text + // segment (counting characters from the beginning of the text). + int64 start_offset = 1; + + // Required. Zero-based character index of the first character past the end of + // the text segment (counting character from the beginning of the text). + // The character at the end_offset is NOT included in the text segment. + int64 end_offset = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/text_sentiment.proto b/google/cloud/automl_v1beta1/proto/text_sentiment.proto new file mode 100644 index 00000000..5444c52b --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/text_sentiment.proto @@ -0,0 +1,80 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_outer_classname = "TextSentimentProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Contains annotation details specific to text sentiment. +message TextSentimentAnnotation { + // Output only. The sentiment with the semantic, as given to the + // [AutoMl.ImportData][google.cloud.automl.v1beta1.AutoMl.ImportData] when populating the dataset from which the model used + // for the prediction had been trained. + // The sentiment values are between 0 and + // Dataset.text_sentiment_dataset_metadata.sentiment_max (inclusive), + // with higher value meaning more positive sentiment. They are completely + // relative, i.e. 0 means least positive sentiment and sentiment_max means + // the most positive from the sentiments present in the train data. Therefore + // e.g. if train data had only negative sentiment, then sentiment_max, would + // be still negative (although least negative). + // The sentiment shouldn't be confused with "score" or "magnitude" + // from the previous Natural Language Sentiment Analysis API. + int32 sentiment = 1; +} + +// Model evaluation metrics for text sentiment problems. +message TextSentimentEvaluationMetrics { + // Output only. Precision. + float precision = 1; + + // Output only. Recall. + float recall = 2; + + // Output only. The harmonic mean of recall and precision. + float f1_score = 3; + + // Output only. Mean absolute error. Only set for the overall model + // evaluation, not for evaluation of a single annotation spec. + float mean_absolute_error = 4; + + // Output only. Mean squared error. Only set for the overall model + // evaluation, not for evaluation of a single annotation spec. + float mean_squared_error = 5; + + // Output only. Linear weighted kappa. Only set for the overall model + // evaluation, not for evaluation of a single annotation spec. + float linear_kappa = 6; + + // Output only. Quadratic weighted kappa. Only set for the overall model + // evaluation, not for evaluation of a single annotation spec. + float quadratic_kappa = 7; + + // Output only. Confusion matrix of the evaluation. + // Only set for the overall model evaluation, not for evaluation of a single + // annotation spec. + ClassificationEvaluationMetrics.ConfusionMatrix confusion_matrix = 8; + + // Output only. The annotation spec ids used for this evaluation. + // Deprecated . + repeated string annotation_spec_id = 9 [deprecated = true]; +} diff --git a/google/cloud/automl_v1beta1/proto/translation.proto b/google/cloud/automl_v1beta1/proto/translation.proto new file mode 100644 index 00000000..8585bd41 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/translation.proto @@ -0,0 +1,69 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/field_behavior.proto"; +import "google/cloud/automl/v1beta1/data_items.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "TranslationProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Dataset metadata that is specific to translation. +message TranslationDatasetMetadata { + // Required. The BCP-47 language code of the source language. + string source_language_code = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. The BCP-47 language code of the target language. + string target_language_code = 2 [(google.api.field_behavior) = REQUIRED]; +} + +// Evaluation metrics for the dataset. +message TranslationEvaluationMetrics { + // Output only. BLEU score. + double bleu_score = 1; + + // Output only. BLEU score for base model. + double base_bleu_score = 2; +} + +// Model metadata that is specific to translation. +message TranslationModelMetadata { + // The resource name of the model to use as a baseline to train the custom + // model. If unset, we use the default base model provided by Google + // Translate. Format: + // `projects/{project_id}/locations/{location_id}/models/{model_id}` + string base_model = 1; + + // Output only. Inferred from the dataset. + // The source languge (The BCP-47 language code) that is used for training. + string source_language_code = 2; + + // Output only. The target languge (The BCP-47 language code) that is used for + // training. + string target_language_code = 3; +} + +// Annotation details specific to translation. +message TranslationAnnotation { + // Output only . The translated content. + TextSnippet translated_content = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/video.proto b/google/cloud/automl_v1beta1/proto/video.proto new file mode 100644 index 00000000..268ae2a8 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/video.proto @@ -0,0 +1,48 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "VideoProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Dataset metadata specific to video classification. +// All Video Classification datasets are treated as multi label. +message VideoClassificationDatasetMetadata { + +} + +// Dataset metadata specific to video object tracking. +message VideoObjectTrackingDatasetMetadata { + +} + +// Model metadata specific to video classification. +message VideoClassificationModelMetadata { + +} + +// Model metadata specific to video object tracking. +message VideoObjectTrackingModelMetadata { + +} diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index 5c6d1f5b..1d9cb516 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -87,13 +87,14 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT + column_spec_path = staticmethod(AutoMlClient.column_spec_path) + parse_column_spec_path = staticmethod(AutoMlClient.parse_column_spec_path) dataset_path = staticmethod(AutoMlClient.dataset_path) - + parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) model_path = staticmethod(AutoMlClient.model_path) - - column_spec_path = staticmethod(AutoMlClient.column_spec_path) - + parse_model_path = staticmethod(AutoMlClient.parse_model_path) table_spec_path = staticmethod(AutoMlClient.table_spec_path) + parse_table_spec_path = staticmethod(AutoMlClient.parse_table_spec_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file @@ -124,16 +125,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1beta1/services/auto_ml/client.py b/google/cloud/automl_v1beta1/services/auto_ml/client.py index 9416b524..dd44b58e 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/client.py @@ -16,6 +16,7 @@ # from collections import OrderedDict +from distutils import util import os import re from typing import Callable, Dict, Sequence, Tuple, Type, Union @@ -27,6 +28,7 @@ from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore @@ -263,16 +265,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -288,25 +293,43 @@ def __init__( if client_options is None: client_options = ClientOptions.ClientOptions() - if client_options.api_endpoint is None: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + ssl_credentials = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + import grpc # type: ignore + + cert, key = client_options.client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + is_mtls = True + else: + creds = SslCredentials() + is_mtls = creds.is_mtls + ssl_credentials = creds.ssl_credentials if is_mtls else None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") if use_mtls_env == "never": - client_options.api_endpoint = self.DEFAULT_ENDPOINT + api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - has_client_cert_source = ( - client_options.client_cert_source is not None - or mtls.has_default_client_cert_source() - ) - client_options.api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT - if has_client_cert_source - else self.DEFAULT_ENDPOINT + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -330,10 +353,9 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=client_options.api_endpoint, + host=api_endpoint, scopes=client_options.scopes, - api_mtls_endpoint=client_options.api_endpoint, - client_cert_source=client_options.client_cert_source, + ssl_channel_credentials=ssl_credentials, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py index d50f2201..642c9f7b 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth +from google import auth # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py index a3c183e4..a8cb2fd7 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py @@ -15,6 +15,7 @@ # limitations under the License. # +import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -24,7 +25,6 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore - import grpc # type: ignore from google.cloud.automl_v1beta1.types import annotation_spec @@ -81,6 +81,7 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -101,14 +102,16 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -131,6 +134,11 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -161,6 +169,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) self._stubs = {} # type: Dict[str, Callable] @@ -226,13 +251,6 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py index c8d24dad..a977ad45 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py @@ -15,11 +15,13 @@ # limitations under the License. # +import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore +from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -123,6 +125,7 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -144,14 +147,16 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -174,12 +179,22 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -199,6 +214,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) # Run the base constructor. super().__init__( @@ -219,13 +251,6 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py index cd313402..3974a08c 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py @@ -82,16 +82,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1beta1/services/prediction_service/client.py b/google/cloud/automl_v1beta1/services/prediction_service/client.py index 81cb0649..747f4c4b 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/client.py @@ -16,6 +16,7 @@ # from collections import OrderedDict +from distutils import util import os import re from typing import Callable, Dict, Sequence, Tuple, Type, Union @@ -27,6 +28,7 @@ from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore @@ -161,16 +163,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -186,25 +191,43 @@ def __init__( if client_options is None: client_options = ClientOptions.ClientOptions() - if client_options.api_endpoint is None: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + ssl_credentials = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + import grpc # type: ignore + + cert, key = client_options.client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + is_mtls = True + else: + creds = SslCredentials() + is_mtls = creds.is_mtls + ssl_credentials = creds.ssl_credentials if is_mtls else None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") if use_mtls_env == "never": - client_options.api_endpoint = self.DEFAULT_ENDPOINT + api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - has_client_cert_source = ( - client_options.client_cert_source is not None - or mtls.has_default_client_cert_source() - ) - client_options.api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT - if has_client_cert_source - else self.DEFAULT_ENDPOINT + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -228,10 +251,9 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=client_options.api_endpoint, + host=api_endpoint, scopes=client_options.scopes, - api_mtls_endpoint=client_options.api_endpoint, - client_cert_source=client_options.client_cert_source, + ssl_channel_credentials=ssl_credentials, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py index bb674eca..04857f4c 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth +from google import auth # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py index 9bc30cdd..3c484247 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py @@ -15,6 +15,7 @@ # limitations under the License. # +import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -24,7 +25,6 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore - import grpc # type: ignore from google.cloud.automl_v1beta1.types import prediction_service @@ -61,6 +61,7 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -81,14 +82,16 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -111,6 +114,11 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -141,6 +149,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) self._stubs = {} # type: Dict[str, Callable] @@ -206,13 +231,6 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py index 2c7d9712..0b1bb638 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py @@ -15,11 +15,13 @@ # limitations under the License. # +import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore +from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -103,6 +105,7 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -124,14 +127,16 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -154,12 +159,22 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -179,6 +194,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) # Run the base constructor. super().__init__( @@ -199,13 +231,6 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/noxfile.py b/noxfile.py index 9c69b3b7..709afdde 100644 --- a/noxfile.py +++ b/noxfile.py @@ -74,7 +74,6 @@ def default(session): session.install("mock", "pytest", "pytest-cov") session.install("-e", ".[pandas,storage]") - session.install("proto-plus==1.8.1") # Run py.test against the unit tests. session.run( @@ -199,36 +198,3 @@ def docfx(session): os.path.join("docs", ""), os.path.join("docs", "_build", "html", ""), ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def docfx(session): - """Build the docfx yaml files for this library.""" - - session.install("-e", ".[pandas,storage]") - session.install("sphinx<3.0.0", "alabaster", "recommonmark", "sphinx-docfx-yaml") - - shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) - session.run( - "sphinx-build", - "-T", # show full traceback on exception - "-N", # no colors - "-D", - ( - "extensions=sphinx.ext.autodoc," - "sphinx.ext.autosummary," - "docfx_yaml.extension," - "sphinx.ext.intersphinx," - "sphinx.ext.coverage," - "sphinx.ext.napoleon," - "sphinx.ext.todo," - "sphinx.ext.viewcode," - "recommonmark" - ), - "-b", - "html", - "-d", - os.path.join("docs", "_build", "doctrees", ""), - os.path.join("docs", ""), - os.path.join("docs", "_build", "html", ""), - ) diff --git a/synth.metadata b/synth.metadata index 6c3bc216..aae13c2d 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,16 +3,16 @@ { "git": { "name": ".", - "remote": "git@github.com:googleapis/python-automl", - "sha": "9b218b1f1cd0caef664e51064baf5f4af07a97c1" + "remote": "https://github.com/googleapis/python-automl.git", + "sha": "8c7d54872a6e5628171f160e1a39a067d5f46563" } }, { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "17de2b31f9450385e739bedeeaac6e1ec4f239a8", - "internalRef": "327504150" + "sha": "4ede77543c77072a2ac9f78353de2de2f8c4c501", + "internalRef": "333125205" } }, { @@ -49,5 +49,221 @@ "generator": "bazel" } } + ], + "generatedFiles": [ + ".coveragerc", + ".flake8", + ".github/CONTRIBUTING.md", + ".github/ISSUE_TEMPLATE/bug_report.md", + ".github/ISSUE_TEMPLATE/feature_request.md", + ".github/ISSUE_TEMPLATE/support_request.md", + ".github/PULL_REQUEST_TEMPLATE.md", + ".github/release-please.yml", + ".gitignore", + ".kokoro/build.sh", + ".kokoro/continuous/common.cfg", + ".kokoro/continuous/continuous.cfg", + ".kokoro/docker/docs/Dockerfile", + ".kokoro/docker/docs/fetch_gpg_keys.sh", + ".kokoro/docs/common.cfg", + ".kokoro/docs/docs-presubmit.cfg", + ".kokoro/docs/docs.cfg", + ".kokoro/presubmit/common.cfg", + ".kokoro/presubmit/presubmit.cfg", + ".kokoro/publish-docs.sh", + ".kokoro/release.sh", + ".kokoro/release/common.cfg", + ".kokoro/release/release.cfg", + ".kokoro/samples/lint/common.cfg", + ".kokoro/samples/lint/continuous.cfg", + ".kokoro/samples/lint/periodic.cfg", + ".kokoro/samples/lint/presubmit.cfg", + ".kokoro/samples/python3.6/common.cfg", + ".kokoro/samples/python3.6/continuous.cfg", + ".kokoro/samples/python3.6/periodic.cfg", + ".kokoro/samples/python3.6/presubmit.cfg", + ".kokoro/samples/python3.7/common.cfg", + ".kokoro/samples/python3.7/continuous.cfg", + ".kokoro/samples/python3.7/periodic.cfg", + ".kokoro/samples/python3.7/presubmit.cfg", + ".kokoro/samples/python3.8/common.cfg", + ".kokoro/samples/python3.8/continuous.cfg", + ".kokoro/samples/python3.8/periodic.cfg", + ".kokoro/samples/python3.8/presubmit.cfg", + ".kokoro/test-samples.sh", + ".kokoro/trampoline.sh", + ".kokoro/trampoline_v2.sh", + ".trampolinerc", + "CODE_OF_CONDUCT.md", + "CONTRIBUTING.rst", + "LICENSE", + "MANIFEST.in", + "docs/_static/custom.css", + "docs/_templates/layout.html", + "docs/automl_v1/services.rst", + "docs/automl_v1/types.rst", + "docs/automl_v1beta1/services.rst", + "docs/automl_v1beta1/types.rst", + "docs/conf.py", + "docs/multiprocessing.rst", + "google/cloud/automl/__init__.py", + "google/cloud/automl/py.typed", + "google/cloud/automl_v1/__init__.py", + "google/cloud/automl_v1/proto/annotation_payload.proto", + "google/cloud/automl_v1/proto/annotation_spec.proto", + "google/cloud/automl_v1/proto/classification.proto", + "google/cloud/automl_v1/proto/data_items.proto", + "google/cloud/automl_v1/proto/dataset.proto", + "google/cloud/automl_v1/proto/detection.proto", + "google/cloud/automl_v1/proto/geometry.proto", + "google/cloud/automl_v1/proto/image.proto", + "google/cloud/automl_v1/proto/io.proto", + "google/cloud/automl_v1/proto/model.proto", + "google/cloud/automl_v1/proto/model_evaluation.proto", + "google/cloud/automl_v1/proto/operations.proto", + "google/cloud/automl_v1/proto/prediction_service.proto", + "google/cloud/automl_v1/proto/service.proto", + "google/cloud/automl_v1/proto/text.proto", + "google/cloud/automl_v1/proto/text_extraction.proto", + "google/cloud/automl_v1/proto/text_segment.proto", + "google/cloud/automl_v1/proto/text_sentiment.proto", + "google/cloud/automl_v1/proto/translation.proto", + "google/cloud/automl_v1/py.typed", + "google/cloud/automl_v1/services/__init__.py", + "google/cloud/automl_v1/services/auto_ml/__init__.py", + "google/cloud/automl_v1/services/auto_ml/async_client.py", + "google/cloud/automl_v1/services/auto_ml/client.py", + "google/cloud/automl_v1/services/auto_ml/pagers.py", + "google/cloud/automl_v1/services/auto_ml/transports/__init__.py", + "google/cloud/automl_v1/services/auto_ml/transports/base.py", + "google/cloud/automl_v1/services/auto_ml/transports/grpc.py", + "google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py", + "google/cloud/automl_v1/services/prediction_service/__init__.py", + "google/cloud/automl_v1/services/prediction_service/async_client.py", + "google/cloud/automl_v1/services/prediction_service/client.py", + "google/cloud/automl_v1/services/prediction_service/transports/__init__.py", + "google/cloud/automl_v1/services/prediction_service/transports/base.py", + "google/cloud/automl_v1/services/prediction_service/transports/grpc.py", + "google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py", + "google/cloud/automl_v1/types/__init__.py", + "google/cloud/automl_v1/types/annotation_payload.py", + "google/cloud/automl_v1/types/annotation_spec.py", + "google/cloud/automl_v1/types/classification.py", + "google/cloud/automl_v1/types/data_items.py", + "google/cloud/automl_v1/types/dataset.py", + "google/cloud/automl_v1/types/detection.py", + "google/cloud/automl_v1/types/geometry.py", + "google/cloud/automl_v1/types/image.py", + "google/cloud/automl_v1/types/io.py", + "google/cloud/automl_v1/types/model.py", + "google/cloud/automl_v1/types/model_evaluation.py", + "google/cloud/automl_v1/types/operations.py", + "google/cloud/automl_v1/types/prediction_service.py", + "google/cloud/automl_v1/types/service.py", + "google/cloud/automl_v1/types/text.py", + "google/cloud/automl_v1/types/text_extraction.py", + "google/cloud/automl_v1/types/text_segment.py", + "google/cloud/automl_v1/types/text_sentiment.py", + "google/cloud/automl_v1/types/translation.py", + "google/cloud/automl_v1beta1/__init__.py", + "google/cloud/automl_v1beta1/proto/annotation_payload.proto", + "google/cloud/automl_v1beta1/proto/annotation_spec.proto", + "google/cloud/automl_v1beta1/proto/classification.proto", + "google/cloud/automl_v1beta1/proto/column_spec.proto", + "google/cloud/automl_v1beta1/proto/data_items.proto", + "google/cloud/automl_v1beta1/proto/data_stats.proto", + "google/cloud/automl_v1beta1/proto/data_types.proto", + "google/cloud/automl_v1beta1/proto/dataset.proto", + "google/cloud/automl_v1beta1/proto/detection.proto", + "google/cloud/automl_v1beta1/proto/geometry.proto", + "google/cloud/automl_v1beta1/proto/image.proto", + "google/cloud/automl_v1beta1/proto/io.proto", + "google/cloud/automl_v1beta1/proto/model.proto", + "google/cloud/automl_v1beta1/proto/model_evaluation.proto", + "google/cloud/automl_v1beta1/proto/operations.proto", + "google/cloud/automl_v1beta1/proto/prediction_service.proto", + "google/cloud/automl_v1beta1/proto/ranges.proto", + "google/cloud/automl_v1beta1/proto/regression.proto", + "google/cloud/automl_v1beta1/proto/service.proto", + "google/cloud/automl_v1beta1/proto/table_spec.proto", + "google/cloud/automl_v1beta1/proto/tables.proto", + "google/cloud/automl_v1beta1/proto/temporal.proto", + "google/cloud/automl_v1beta1/proto/text.proto", + "google/cloud/automl_v1beta1/proto/text_extraction.proto", + "google/cloud/automl_v1beta1/proto/text_segment.proto", + "google/cloud/automl_v1beta1/proto/text_sentiment.proto", + "google/cloud/automl_v1beta1/proto/translation.proto", + "google/cloud/automl_v1beta1/proto/video.proto", + "google/cloud/automl_v1beta1/py.typed", + "google/cloud/automl_v1beta1/services/__init__.py", + "google/cloud/automl_v1beta1/services/auto_ml/__init__.py", + "google/cloud/automl_v1beta1/services/auto_ml/async_client.py", + "google/cloud/automl_v1beta1/services/auto_ml/client.py", + "google/cloud/automl_v1beta1/services/auto_ml/pagers.py", + "google/cloud/automl_v1beta1/services/auto_ml/transports/__init__.py", + "google/cloud/automl_v1beta1/services/auto_ml/transports/base.py", + "google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py", + "google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py", + "google/cloud/automl_v1beta1/services/prediction_service/__init__.py", + "google/cloud/automl_v1beta1/services/prediction_service/async_client.py", + "google/cloud/automl_v1beta1/services/prediction_service/client.py", + "google/cloud/automl_v1beta1/services/prediction_service/transports/__init__.py", + "google/cloud/automl_v1beta1/services/prediction_service/transports/base.py", + "google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py", + "google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py", + "google/cloud/automl_v1beta1/types/__init__.py", + "google/cloud/automl_v1beta1/types/annotation_payload.py", + "google/cloud/automl_v1beta1/types/annotation_spec.py", + "google/cloud/automl_v1beta1/types/classification.py", + "google/cloud/automl_v1beta1/types/column_spec.py", + "google/cloud/automl_v1beta1/types/data_items.py", + "google/cloud/automl_v1beta1/types/data_stats.py", + "google/cloud/automl_v1beta1/types/data_types.py", + "google/cloud/automl_v1beta1/types/dataset.py", + "google/cloud/automl_v1beta1/types/detection.py", + "google/cloud/automl_v1beta1/types/geometry.py", + "google/cloud/automl_v1beta1/types/image.py", + "google/cloud/automl_v1beta1/types/io.py", + "google/cloud/automl_v1beta1/types/model.py", + "google/cloud/automl_v1beta1/types/model_evaluation.py", + "google/cloud/automl_v1beta1/types/operations.py", + "google/cloud/automl_v1beta1/types/prediction_service.py", + "google/cloud/automl_v1beta1/types/ranges.py", + "google/cloud/automl_v1beta1/types/regression.py", + "google/cloud/automl_v1beta1/types/service.py", + "google/cloud/automl_v1beta1/types/table_spec.py", + "google/cloud/automl_v1beta1/types/tables.py", + "google/cloud/automl_v1beta1/types/temporal.py", + "google/cloud/automl_v1beta1/types/text.py", + "google/cloud/automl_v1beta1/types/text_extraction.py", + "google/cloud/automl_v1beta1/types/text_segment.py", + "google/cloud/automl_v1beta1/types/text_sentiment.py", + "google/cloud/automl_v1beta1/types/translation.py", + "google/cloud/automl_v1beta1/types/video.py", + "mypy.ini", + "noxfile.py", + "renovate.json", + "samples/AUTHORING_GUIDE.md", + "samples/CONTRIBUTING.md", + "samples/beta/noxfile.py", + "samples/snippets/noxfile.py", + "samples/tables/noxfile.py", + "scripts/decrypt-secrets.sh", + "scripts/fixup_automl_v1_keywords.py", + "scripts/fixup_automl_v1beta1_keywords.py", + "scripts/readme-gen/readme_gen.py", + "scripts/readme-gen/templates/README.tmpl.rst", + "scripts/readme-gen/templates/auth.tmpl.rst", + "scripts/readme-gen/templates/auth_api_key.tmpl.rst", + "scripts/readme-gen/templates/install_deps.tmpl.rst", + "scripts/readme-gen/templates/install_portaudio.tmpl.rst", + "setup.cfg", + "testing/.gitignore", + "tests/unit/gapic/automl_v1/__init__.py", + "tests/unit/gapic/automl_v1/test_auto_ml.py", + "tests/unit/gapic/automl_v1/test_prediction_service.py", + "tests/unit/gapic/automl_v1beta1/__init__.py", + "tests/unit/gapic/automl_v1beta1/test_auto_ml.py", + "tests/unit/gapic/automl_v1beta1/test_prediction_service.py" ] } \ No newline at end of file diff --git a/tests/unit/gapic/automl_v1/test_auto_ml.py b/tests/unit/gapic/automl_v1/test_auto_ml.py index 42ad394e..a567c98f 100644 --- a/tests/unit/gapic/automl_v1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1/test_auto_ml.py @@ -158,15 +158,14 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -175,15 +174,14 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -192,95 +190,171 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "true"), + ( + AutoMlAsyncClient, + transports.AutoMlGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "false"), + ( + AutoMlAsyncClient, + transports.AutoMlGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + AutoMlClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlClient) +) +@mock.patch.object( + AutoMlAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlAsyncClient) +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_auto_ml_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=client_cert_source_callback, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and default_client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): - with mock.patch.object(transport_class, "__init__") as patched: + ssl_channel_creds = mock.Mock() with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, + "grpc.ssl_channel_credentials", return_value=ssl_channel_creds ): patched.return_value = None - client = client_class() + client = client_class(client_options=options) + + if use_client_cert_env == "false": + expected_ssl_channel_creds = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_ssl_channel_creds = ssl_channel_creds + expected_host = client.DEFAULT_MTLS_ENDPOINT + patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, + host=expected_host, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=expected_ssl_channel_creds, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", but client_cert_source and default_client_cert_source are None. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None ): - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.ssl_credentials", + new_callable=mock.PropertyMock, + ) as ssl_credentials_mock: + if use_client_cert_env == "false": + is_mtls_mock.return_value = False + ssl_credentials_mock.return_value = None + expected_host = client.DEFAULT_ENDPOINT + expected_ssl_channel_creds = None + else: + is_mtls_mock.return_value = True + ssl_credentials_mock.return_value = mock.Mock() + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_ssl_channel_creds = ( + ssl_credentials_mock.return_value + ) + + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + ssl_channel_credentials=expected_ssl_channel_creds, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + ): + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + is_mtls_mock.return_value = False + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -303,8 +377,7 @@ def test_auto_ml_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -330,8 +403,7 @@ def test_auto_ml_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -348,8 +420,7 @@ def test_auto_ml_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -1038,8 +1109,8 @@ def test_list_datasets_pages(): RuntimeError, ) pages = list(client.list_datasets(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -1103,10 +1174,10 @@ async def test_list_datasets_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_datasets(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_datasets(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_update_dataset( @@ -2862,8 +2933,8 @@ def test_list_models_pages(): RuntimeError, ) pages = list(client.list_models(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -2919,10 +2990,10 @@ async def test_list_models_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_models(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_models(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelRequest): @@ -4459,8 +4530,8 @@ def test_list_model_evaluations_pages(): RuntimeError, ) pages = list(client.list_model_evaluations(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -4544,10 +4615,10 @@ async def test_list_model_evaluations_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_model_evaluations(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_model_evaluations(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_credentials_transport_error(): @@ -4604,6 +4675,18 @@ def test_transport_get_channel(): assert channel +@pytest.mark.parametrize( + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4680,6 +4763,17 @@ def test_auto_ml_base_transport_with_credentials_file(): ) +def test_auto_ml_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(auth, "default") as adc, mock.patch( + "google.cloud.automl_v1.services.auto_ml.transports.AutoMlTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.AutoMlTransport() + adc.assert_called_once() + + def test_auto_ml_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -4728,179 +4822,102 @@ def test_auto_ml_host_with_port(): def test_auto_ml_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called def test_auto_ml_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_auto_ml_grpc_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], ) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_auto_ml_grpc_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - mock_cred = mock.Mock() - transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel +def test_auto_ml_transport_channel_mtls_with_client_cert_source(transport_class): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], ) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. +def test_auto_ml_transport_channel_mtls_with_adc(transport_class): mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - mock_cred = mock.Mock() - transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_auto_ml_grpc_lro_client(): @@ -4929,53 +4946,53 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_model_path(): +def test_dataset_path(): project = "squid" location = "clam" - model = "whelk" + dataset = "whelk" - expected = "projects/{project}/locations/{location}/models/{model}".format( - project=project, location=location, model=model, + expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( + project=project, location=location, dataset=dataset, ) - actual = AutoMlClient.model_path(project, location, model) + actual = AutoMlClient.dataset_path(project, location, dataset) assert expected == actual -def test_parse_model_path(): +def test_parse_dataset_path(): expected = { "project": "octopus", "location": "oyster", - "model": "nudibranch", + "dataset": "nudibranch", } - path = AutoMlClient.model_path(**expected) + path = AutoMlClient.dataset_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_model_path(path) + actual = AutoMlClient.parse_dataset_path(path) assert expected == actual -def test_dataset_path(): +def test_model_path(): project = "squid" location = "clam" - dataset = "whelk" + model = "whelk" - expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( - project=project, location=location, dataset=dataset, + expected = "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, ) - actual = AutoMlClient.dataset_path(project, location, dataset) + actual = AutoMlClient.model_path(project, location, model) assert expected == actual -def test_parse_dataset_path(): +def test_parse_model_path(): expected = { "project": "octopus", "location": "oyster", - "dataset": "nudibranch", + "model": "nudibranch", } - path = AutoMlClient.dataset_path(**expected) + path = AutoMlClient.model_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_dataset_path(path) + actual = AutoMlClient.parse_model_path(path) assert expected == actual diff --git a/tests/unit/gapic/automl_v1/test_prediction_service.py b/tests/unit/gapic/automl_v1/test_prediction_service.py index a0087eae..37efdce5 100644 --- a/tests/unit/gapic/automl_v1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1/test_prediction_service.py @@ -167,15 +167,14 @@ def test_prediction_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -184,15 +183,14 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -201,95 +199,185 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + PredictionServiceClient, + transports.PredictionServiceGrpcTransport, + "grpc", + "true", + ), + ( + PredictionServiceAsyncClient, + transports.PredictionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + PredictionServiceClient, + transports.PredictionServiceGrpcTransport, + "grpc", + "false", + ), + ( + PredictionServiceAsyncClient, + transports.PredictionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + PredictionServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceClient), +) +@mock.patch.object( + PredictionServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_prediction_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=client_cert_source_callback, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and default_client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): - with mock.patch.object(transport_class, "__init__") as patched: + ssl_channel_creds = mock.Mock() with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, + "grpc.ssl_channel_credentials", return_value=ssl_channel_creds ): patched.return_value = None - client = client_class() + client = client_class(client_options=options) + + if use_client_cert_env == "false": + expected_ssl_channel_creds = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_ssl_channel_creds = ssl_channel_creds + expected_host = client.DEFAULT_MTLS_ENDPOINT + patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, + host=expected_host, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=expected_ssl_channel_creds, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", but client_cert_source and default_client_cert_source are None. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None ): - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.ssl_credentials", + new_callable=mock.PropertyMock, + ) as ssl_credentials_mock: + if use_client_cert_env == "false": + is_mtls_mock.return_value = False + ssl_credentials_mock.return_value = None + expected_host = client.DEFAULT_ENDPOINT + expected_ssl_channel_creds = None + else: + is_mtls_mock.return_value = True + ssl_credentials_mock.return_value = mock.Mock() + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_ssl_channel_creds = ( + ssl_credentials_mock.return_value + ) + + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + ssl_channel_credentials=expected_ssl_channel_creds, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + ): + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + is_mtls_mock.return_value = False + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -316,8 +404,7 @@ def test_prediction_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -347,8 +434,7 @@ def test_prediction_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -367,8 +453,7 @@ def test_prediction_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -904,6 +989,21 @@ def test_transport_get_channel(): assert channel +@pytest.mark.parametrize( + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -964,6 +1064,17 @@ def test_prediction_service_base_transport_with_credentials_file(): ) +def test_prediction_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(auth, "default") as adc, mock.patch( + "google.cloud.automl_v1.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport() + adc.assert_called_once() + + def test_prediction_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -1012,179 +1123,110 @@ def test_prediction_service_host_with_port(): def test_prediction_service_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called def test_prediction_service_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_prediction_service_grpc_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], ) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_prediction_service_grpc_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint +def test_prediction_service_transport_channel_mtls_with_client_cert_source( + transport_class, ): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - mock_cred = mock.Mock() - transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], ) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. +def test_prediction_service_transport_channel_mtls_with_adc(transport_class): mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - mock_cred = mock.Mock() - transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_prediction_service_grpc_lro_client(): diff --git a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py index 2464c824..ebb97c59 100644 --- a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py @@ -168,15 +168,14 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -185,15 +184,14 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -202,95 +200,171 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "true"), + ( + AutoMlAsyncClient, + transports.AutoMlGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "false"), + ( + AutoMlAsyncClient, + transports.AutoMlGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + AutoMlClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlClient) +) +@mock.patch.object( + AutoMlAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlAsyncClient) +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_auto_ml_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=client_cert_source_callback, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and default_client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): - with mock.patch.object(transport_class, "__init__") as patched: + ssl_channel_creds = mock.Mock() with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, + "grpc.ssl_channel_credentials", return_value=ssl_channel_creds ): patched.return_value = None - client = client_class() + client = client_class(client_options=options) + + if use_client_cert_env == "false": + expected_ssl_channel_creds = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_ssl_channel_creds = ssl_channel_creds + expected_host = client.DEFAULT_MTLS_ENDPOINT + patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, + host=expected_host, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=expected_ssl_channel_creds, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", but client_cert_source and default_client_cert_source are None. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None ): - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.ssl_credentials", + new_callable=mock.PropertyMock, + ) as ssl_credentials_mock: + if use_client_cert_env == "false": + is_mtls_mock.return_value = False + ssl_credentials_mock.return_value = None + expected_host = client.DEFAULT_ENDPOINT + expected_ssl_channel_creds = None + else: + is_mtls_mock.return_value = True + ssl_credentials_mock.return_value = mock.Mock() + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_ssl_channel_creds = ( + ssl_credentials_mock.return_value + ) + + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + ssl_channel_credentials=expected_ssl_channel_creds, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + ): + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + is_mtls_mock.return_value = False + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -313,8 +387,7 @@ def test_auto_ml_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -340,8 +413,7 @@ def test_auto_ml_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -358,8 +430,7 @@ def test_auto_ml_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -1079,8 +1150,8 @@ def test_list_datasets_pages(): RuntimeError, ) pages = list(client.list_datasets(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -1144,10 +1215,10 @@ async def test_list_datasets_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_datasets(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_datasets(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_update_dataset( @@ -2711,8 +2782,8 @@ def test_list_table_specs_pages(): RuntimeError, ) pages = list(client.list_table_specs(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -2784,10 +2855,10 @@ async def test_list_table_specs_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_table_specs(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_table_specs(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_update_table_spec( @@ -3494,8 +3565,8 @@ def test_list_column_specs_pages(): RuntimeError, ) pages = list(client.list_column_specs(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -3567,10 +3638,10 @@ async def test_list_column_specs_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_column_specs(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_column_specs(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_update_column_spec( @@ -4455,8 +4526,8 @@ def test_list_models_pages(): RuntimeError, ) pages = list(client.list_models(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -4512,10 +4583,10 @@ async def test_list_models_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_models(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_models(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelRequest): @@ -6013,8 +6084,8 @@ def test_list_model_evaluations_pages(): RuntimeError, ) pages = list(client.list_model_evaluations(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -6098,10 +6169,10 @@ async def test_list_model_evaluations_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_model_evaluations(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_model_evaluations(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_credentials_transport_error(): @@ -6158,6 +6229,18 @@ def test_transport_get_channel(): assert channel +@pytest.mark.parametrize( + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -6240,6 +6323,17 @@ def test_auto_ml_base_transport_with_credentials_file(): ) +def test_auto_ml_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(auth, "default") as adc, mock.patch( + "google.cloud.automl_v1beta1.services.auto_ml.transports.AutoMlTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.AutoMlTransport() + adc.assert_called_once() + + def test_auto_ml_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -6288,179 +6382,102 @@ def test_auto_ml_host_with_port(): def test_auto_ml_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called def test_auto_ml_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_auto_ml_grpc_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], ) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_auto_ml_grpc_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - mock_cred = mock.Mock() - transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel +def test_auto_ml_transport_channel_mtls_with_client_cert_source(transport_class): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], ) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. +def test_auto_ml_transport_channel_mtls_with_adc(transport_class): mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - mock_cred = mock.Mock() - transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_auto_ml_grpc_lro_client(): @@ -6489,6 +6506,41 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client +def test_column_spec_path(): + project = "squid" + location = "clam" + dataset = "whelk" + table_spec = "octopus" + column_spec = "oyster" + + expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}".format( + project=project, + location=location, + dataset=dataset, + table_spec=table_spec, + column_spec=column_spec, + ) + actual = AutoMlClient.column_spec_path( + project, location, dataset, table_spec, column_spec + ) + assert expected == actual + + +def test_parse_column_spec_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "dataset": "mussel", + "table_spec": "winkle", + "column_spec": "nautilus", + } + path = AutoMlClient.column_spec_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_column_spec_path(path) + assert expected == actual + + def test_dataset_path(): project = "squid" location = "clam" @@ -6539,41 +6591,6 @@ def test_parse_model_path(): assert expected == actual -def test_column_spec_path(): - project = "squid" - location = "clam" - dataset = "whelk" - table_spec = "octopus" - column_spec = "oyster" - - expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}".format( - project=project, - location=location, - dataset=dataset, - table_spec=table_spec, - column_spec=column_spec, - ) - actual = AutoMlClient.column_spec_path( - project, location, dataset, table_spec, column_spec - ) - assert expected == actual - - -def test_parse_column_spec_path(): - expected = { - "project": "nudibranch", - "location": "cuttlefish", - "dataset": "mussel", - "table_spec": "winkle", - "column_spec": "nautilus", - } - path = AutoMlClient.column_spec_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_column_spec_path(path) - assert expected == actual - - def test_table_spec_path(): project = "squid" location = "clam" diff --git a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py index c21f17b9..4d9e45a9 100644 --- a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py @@ -170,15 +170,14 @@ def test_prediction_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -187,15 +186,14 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -204,95 +202,185 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + PredictionServiceClient, + transports.PredictionServiceGrpcTransport, + "grpc", + "true", + ), + ( + PredictionServiceAsyncClient, + transports.PredictionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + PredictionServiceClient, + transports.PredictionServiceGrpcTransport, + "grpc", + "false", + ), + ( + PredictionServiceAsyncClient, + transports.PredictionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + PredictionServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceClient), +) +@mock.patch.object( + PredictionServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_prediction_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=client_cert_source_callback, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and default_client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): - with mock.patch.object(transport_class, "__init__") as patched: + ssl_channel_creds = mock.Mock() with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, + "grpc.ssl_channel_credentials", return_value=ssl_channel_creds ): patched.return_value = None - client = client_class() + client = client_class(client_options=options) + + if use_client_cert_env == "false": + expected_ssl_channel_creds = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_ssl_channel_creds = ssl_channel_creds + expected_host = client.DEFAULT_MTLS_ENDPOINT + patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, + host=expected_host, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=expected_ssl_channel_creds, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", but client_cert_source and default_client_cert_source are None. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None ): - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.ssl_credentials", + new_callable=mock.PropertyMock, + ) as ssl_credentials_mock: + if use_client_cert_env == "false": + is_mtls_mock.return_value = False + ssl_credentials_mock.return_value = None + expected_host = client.DEFAULT_ENDPOINT + expected_ssl_channel_creds = None + else: + is_mtls_mock.return_value = True + ssl_credentials_mock.return_value = mock.Mock() + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_ssl_channel_creds = ( + ssl_credentials_mock.return_value + ) + + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + ssl_channel_credentials=expected_ssl_channel_creds, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + ): + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + is_mtls_mock.return_value = False + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -319,8 +407,7 @@ def test_prediction_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -350,8 +437,7 @@ def test_prediction_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -370,8 +456,7 @@ def test_prediction_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -907,6 +992,21 @@ def test_transport_get_channel(): assert channel +@pytest.mark.parametrize( + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -967,6 +1067,17 @@ def test_prediction_service_base_transport_with_credentials_file(): ) +def test_prediction_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(auth, "default") as adc, mock.patch( + "google.cloud.automl_v1beta1.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport() + adc.assert_called_once() + + def test_prediction_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -1015,179 +1126,110 @@ def test_prediction_service_host_with_port(): def test_prediction_service_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called def test_prediction_service_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_prediction_service_grpc_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], ) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_prediction_service_grpc_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint +def test_prediction_service_transport_channel_mtls_with_client_cert_source( + transport_class, ): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - mock_cred = mock.Mock() - transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], ) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. +def test_prediction_service_transport_channel_mtls_with_adc(transport_class): mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - mock_cred = mock.Mock() - transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_prediction_service_grpc_lro_client(): From d70ff4bf35fd509103bdf73a3b33921c4e9845ee Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:57:45 -0700 Subject: [PATCH 10/25] docs: update OPTIONAL annotations for some fields. PiperOrigin-RevId: 333132625 Source-Author: Google APIs Source-Date: Tue Sep 22 12:14:18 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: 470d84e263c833af5280753b8e4188432b8d5b06 Source-Link: https://github.com/googleapis/googleapis/commit/470d84e263c833af5280753b8e4188432b8d5b06 --- google/cloud/automl_v1beta1/__init__.py | 4 ++-- synth.metadata | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 30db2703..44f619cb 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -149,6 +149,7 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", + "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -227,7 +228,6 @@ "OutputConfig", "PredictRequest", "PredictResponse", - "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "AutoMlClient", + "PredictionServiceClient", ) diff --git a/synth.metadata b/synth.metadata index aae13c2d..55adc856 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "4ede77543c77072a2ac9f78353de2de2f8c4c501", - "internalRef": "333125205" + "sha": "470d84e263c833af5280753b8e4188432b8d5b06", + "internalRef": "333132625" } }, { From c194d325361a53a6d5d5d3d81a947c9ba382a4af Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:57:45 -0700 Subject: [PATCH 11/25] Update gapic-generator-python pin to 0.33.4 PiperOrigin-RevId: 333159182 Source-Author: Google APIs Source-Date: Tue Sep 22 14:22:59 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: 3dbeac0d54125b123c8dfd39c774b37473c36944 Source-Link: https://github.com/googleapis/googleapis/commit/3dbeac0d54125b123c8dfd39c774b37473c36944 --- .../services/auto_ml/async_client.py | 4 +-- .../automl_v1/services/auto_ml/client.py | 22 +++++++-------- .../prediction_service/async_client.py | 4 +-- .../services/prediction_service/client.py | 22 +++++++-------- google/cloud/automl_v1beta1/__init__.py | 4 +-- .../services/auto_ml/async_client.py | 28 +++++++++---------- .../automl_v1beta1/services/auto_ml/client.py | 22 +++++++-------- .../services/auto_ml/transports/base.py | 24 ++++++++-------- .../prediction_service/async_client.py | 4 +-- .../services/prediction_service/client.py | 22 +++++++-------- .../automl_v1beta1/types/classification.py | 4 +-- .../cloud/automl_v1beta1/types/data_stats.py | 8 +++--- synth.metadata | 4 +-- tests/unit/gapic/automl_v1/test_auto_ml.py | 2 +- .../automl_v1/test_prediction_service.py | 2 +- .../unit/gapic/automl_v1beta1/test_auto_ml.py | 2 +- .../automl_v1beta1/test_prediction_service.py | 2 +- 17 files changed, 90 insertions(+), 90 deletions(-) diff --git a/google/cloud/automl_v1/services/auto_ml/async_client.py b/google/cloud/automl_v1/services/auto_ml/async_client.py index 9dd21f72..23d7b118 100644 --- a/google/cloud/automl_v1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1/services/auto_ml/async_client.py @@ -28,8 +28,8 @@ from google.auth import credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1.services.auto_ml import pagers from google.cloud.automl_v1.types import annotation_spec from google.cloud.automl_v1.types import classification diff --git a/google/cloud/automl_v1/services/auto_ml/client.py b/google/cloud/automl_v1/services/auto_ml/client.py index 6cace8ae..3765ac0b 100644 --- a/google/cloud/automl_v1/services/auto_ml/client.py +++ b/google/cloud/automl_v1/services/auto_ml/client.py @@ -19,10 +19,10 @@ from distutils import util import os import re -from typing import Callable, Dict, Sequence, Tuple, Type, Union +from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore +from google.api_core import client_options as client_options_lib # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore @@ -32,8 +32,8 @@ from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1.services.auto_ml import pagers from google.cloud.automl_v1.types import annotation_spec from google.cloud.automl_v1.types import classification @@ -198,9 +198,9 @@ def parse_model_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: credentials.Credentials = None, - transport: Union[str, AutoMlTransport] = None, - client_options: ClientOptions = None, + credentials: Optional[credentials.Credentials] = None, + transport: Union[str, AutoMlTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the auto ml client. @@ -214,8 +214,8 @@ def __init__( transport (Union[str, ~.AutoMlTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. + client_options (client_options_lib.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: @@ -241,9 +241,9 @@ def __init__( creation failed for any reason. """ if isinstance(client_options, dict): - client_options = ClientOptions.from_dict(client_options) + client_options = client_options_lib.from_dict(client_options) if client_options is None: - client_options = ClientOptions.ClientOptions() + client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. use_client_cert = bool( diff --git a/google/cloud/automl_v1/services/prediction_service/async_client.py b/google/cloud/automl_v1/services/prediction_service/async_client.py index fe1d2226..d77836a0 100644 --- a/google/cloud/automl_v1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1/services/prediction_service/async_client.py @@ -28,8 +28,8 @@ from google.auth import credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1.types import annotation_payload from google.cloud.automl_v1.types import data_items from google.cloud.automl_v1.types import io diff --git a/google/cloud/automl_v1/services/prediction_service/client.py b/google/cloud/automl_v1/services/prediction_service/client.py index d557fd9b..d2c1971a 100644 --- a/google/cloud/automl_v1/services/prediction_service/client.py +++ b/google/cloud/automl_v1/services/prediction_service/client.py @@ -19,10 +19,10 @@ from distutils import util import os import re -from typing import Callable, Dict, Sequence, Tuple, Type, Union +from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore +from google.api_core import client_options as client_options_lib # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore @@ -32,8 +32,8 @@ from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1.types import annotation_payload from google.cloud.automl_v1.types import data_items from google.cloud.automl_v1.types import io @@ -144,9 +144,9 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): def __init__( self, *, - credentials: credentials.Credentials = None, - transport: Union[str, PredictionServiceTransport] = None, - client_options: ClientOptions = None, + credentials: Optional[credentials.Credentials] = None, + transport: Union[str, PredictionServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the prediction service client. @@ -160,8 +160,8 @@ def __init__( transport (Union[str, ~.PredictionServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. + client_options (client_options_lib.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: @@ -187,9 +187,9 @@ def __init__( creation failed for any reason. """ if isinstance(client_options, dict): - client_options = ClientOptions.from_dict(client_options) + client_options = client_options_lib.from_dict(client_options) if client_options is None: - client_options = ClientOptions.ClientOptions() + client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. use_client_cert = bool( diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 44f619cb..30db2703 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -149,7 +149,6 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", - "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -228,6 +227,7 @@ "OutputConfig", "PredictRequest", "PredictResponse", + "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "PredictionServiceClient", + "AutoMlClient", ) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index 1d9cb516..55d60100 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -28,8 +28,8 @@ from google.auth import credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1beta1.services.auto_ml import pagers from google.cloud.automl_v1beta1.types import annotation_spec from google.cloud.automl_v1beta1.types import classification @@ -294,7 +294,7 @@ async def get_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -376,7 +376,7 @@ async def list_datasets( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -555,7 +555,7 @@ async def delete_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -860,7 +860,7 @@ async def get_annotation_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -948,7 +948,7 @@ async def get_table_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1030,7 +1030,7 @@ async def list_table_specs( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1200,7 +1200,7 @@ async def get_column_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1282,7 +1282,7 @@ async def list_column_specs( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1537,7 +1537,7 @@ async def get_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1619,7 +1619,7 @@ async def list_models( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1722,7 +1722,7 @@ async def delete_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -2248,7 +2248,7 @@ async def get_model_evaluation( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1beta1/services/auto_ml/client.py b/google/cloud/automl_v1beta1/services/auto_ml/client.py index dd44b58e..6ae4f4c2 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/client.py @@ -19,10 +19,10 @@ from distutils import util import os import re -from typing import Callable, Dict, Sequence, Tuple, Type, Union +from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore +from google.api_core import client_options as client_options_lib # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore @@ -32,8 +32,8 @@ from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1beta1.services.auto_ml import pagers from google.cloud.automl_v1beta1.types import annotation_spec from google.cloud.automl_v1beta1.types import classification @@ -246,9 +246,9 @@ def parse_table_spec_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: credentials.Credentials = None, - transport: Union[str, AutoMlTransport] = None, - client_options: ClientOptions = None, + credentials: Optional[credentials.Credentials] = None, + transport: Union[str, AutoMlTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the auto ml client. @@ -262,8 +262,8 @@ def __init__( transport (Union[str, ~.AutoMlTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. + client_options (client_options_lib.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: @@ -289,9 +289,9 @@ def __init__( creation failed for any reason. """ if isinstance(client_options, dict): - client_options = ClientOptions.from_dict(client_options) + client_options = client_options_lib.from_dict(client_options) if client_options is None: - client_options = ClientOptions.ClientOptions() + client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. use_client_cert = bool( diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py index 642c9f7b..63f0601f 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py @@ -125,7 +125,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -138,7 +138,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -154,7 +154,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -173,7 +173,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -186,7 +186,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -199,7 +199,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -215,7 +215,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -228,7 +228,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -247,7 +247,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -260,7 +260,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -273,7 +273,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -300,7 +300,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py index 3974a08c..c204325b 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py @@ -28,8 +28,8 @@ from google.auth import credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1beta1.types import annotation_payload from google.cloud.automl_v1beta1.types import data_items from google.cloud.automl_v1beta1.types import io diff --git a/google/cloud/automl_v1beta1/services/prediction_service/client.py b/google/cloud/automl_v1beta1/services/prediction_service/client.py index 747f4c4b..78ec510c 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/client.py @@ -19,10 +19,10 @@ from distutils import util import os import re -from typing import Callable, Dict, Sequence, Tuple, Type, Union +from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore +from google.api_core import client_options as client_options_lib # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore @@ -32,8 +32,8 @@ from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1beta1.types import annotation_payload from google.cloud.automl_v1beta1.types import data_items from google.cloud.automl_v1beta1.types import io @@ -144,9 +144,9 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): def __init__( self, *, - credentials: credentials.Credentials = None, - transport: Union[str, PredictionServiceTransport] = None, - client_options: ClientOptions = None, + credentials: Optional[credentials.Credentials] = None, + transport: Union[str, PredictionServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the prediction service client. @@ -160,8 +160,8 @@ def __init__( transport (Union[str, ~.PredictionServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. + client_options (client_options_lib.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: @@ -187,9 +187,9 @@ def __init__( creation failed for any reason. """ if isinstance(client_options, dict): - client_options = ClientOptions.from_dict(client_options) + client_options = client_options_lib.from_dict(client_options) if client_options is None: - client_options = ClientOptions.ClientOptions() + client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. use_client_cert = bool( diff --git a/google/cloud/automl_v1beta1/types/classification.py b/google/cloud/automl_v1beta1/types/classification.py index 8c879bf2..4b5e5a2a 100644 --- a/google/cloud/automl_v1beta1/types/classification.py +++ b/google/cloud/automl_v1beta1/types/classification.py @@ -60,7 +60,7 @@ class VideoClassificationAnnotation(proto.Message): r"""Contains annotation details specific to video classification. Attributes: - type (str): + type_ (str): Output only. Expresses the type of video classification. Possible values: @@ -96,7 +96,7 @@ class VideoClassificationAnnotation(proto.Message): to which the annotation applies. """ - type = proto.Field(proto.STRING, number=1) + type_ = proto.Field(proto.STRING, number=1) classification_annotation = proto.Field( proto.MESSAGE, number=2, message=ClassificationAnnotation, diff --git a/google/cloud/automl_v1beta1/types/data_stats.py b/google/cloud/automl_v1beta1/types/data_stats.py index 4ae40fc8..4405185f 100644 --- a/google/cloud/automl_v1beta1/types/data_stats.py +++ b/google/cloud/automl_v1beta1/types/data_stats.py @@ -115,9 +115,9 @@ class HistogramBucket(proto.Message): r"""A bucket of a histogram. Attributes: - min (float): + min_ (float): The minimum value of the bucket, inclusive. - max (float): + max_ (float): The maximum value of the bucket, exclusive unless max = ``"Infinity"``, in which case it's inclusive. count (int): @@ -125,9 +125,9 @@ class HistogramBucket(proto.Message): bucket, i.e. are between min and max values. """ - min = proto.Field(proto.DOUBLE, number=1) + min_ = proto.Field(proto.DOUBLE, number=1) - max = proto.Field(proto.DOUBLE, number=2) + max_ = proto.Field(proto.DOUBLE, number=2) count = proto.Field(proto.INT64, number=3) diff --git a/synth.metadata b/synth.metadata index 55adc856..6ec73253 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "470d84e263c833af5280753b8e4188432b8d5b06", - "internalRef": "333132625" + "sha": "3dbeac0d54125b123c8dfd39c774b37473c36944", + "internalRef": "333159182" } }, { diff --git a/tests/unit/gapic/automl_v1/test_auto_ml.py b/tests/unit/gapic/automl_v1/test_auto_ml.py index a567c98f..a11480cd 100644 --- a/tests/unit/gapic/automl_v1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1/test_auto_ml.py @@ -31,7 +31,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.api_core import operation_async +from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 from google.auth import credentials from google.auth.exceptions import MutualTLSChannelError diff --git a/tests/unit/gapic/automl_v1/test_prediction_service.py b/tests/unit/gapic/automl_v1/test_prediction_service.py index 37efdce5..fd886203 100644 --- a/tests/unit/gapic/automl_v1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1/test_prediction_service.py @@ -31,7 +31,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.api_core import operation_async +from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 from google.auth import credentials from google.auth.exceptions import MutualTLSChannelError diff --git a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py index ebb97c59..09cb0749 100644 --- a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py @@ -31,7 +31,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.api_core import operation_async +from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 from google.auth import credentials from google.auth.exceptions import MutualTLSChannelError diff --git a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py index 4d9e45a9..44c966c5 100644 --- a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py @@ -31,7 +31,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.api_core import operation_async +from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 from google.auth import credentials from google.auth.exceptions import MutualTLSChannelError From 21b454cbed0bbe2a5eec580b2c1b090d4d366f4b Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:58:19 -0700 Subject: [PATCH 12/25] chore: use Python microgenerator rules for aiplatform PiperOrigin-RevId: 333302099 Source-Author: Google APIs Source-Date: Wed Sep 23 08:58:22 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: acd4aabf1c1e3e5bf7db0e81f323003fb317fdaa Source-Link: https://github.com/googleapis/googleapis/commit/acd4aabf1c1e3e5bf7db0e81f323003fb317fdaa --- google/cloud/automl_v1beta1/__init__.py | 4 ++-- .../services/auto_ml/async_client.py | 24 +++++++++---------- .../services/auto_ml/transports/base.py | 24 +++++++++---------- synth.metadata | 4 ++-- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 30db2703..44f619cb 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -149,6 +149,7 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", + "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -227,7 +228,6 @@ "OutputConfig", "PredictRequest", "PredictResponse", - "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "AutoMlClient", + "PredictionServiceClient", ) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index 55d60100..b7a10974 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -294,7 +294,7 @@ async def get_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -376,7 +376,7 @@ async def list_datasets( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -555,7 +555,7 @@ async def delete_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -860,7 +860,7 @@ async def get_annotation_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -948,7 +948,7 @@ async def get_table_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1030,7 +1030,7 @@ async def list_table_specs( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1200,7 +1200,7 @@ async def get_column_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1282,7 +1282,7 @@ async def list_column_specs( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1537,7 +1537,7 @@ async def get_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1619,7 +1619,7 @@ async def list_models( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1722,7 +1722,7 @@ async def delete_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -2248,7 +2248,7 @@ async def get_model_evaluation( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py index 63f0601f..642c9f7b 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py @@ -125,7 +125,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -138,7 +138,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -154,7 +154,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -173,7 +173,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -186,7 +186,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -199,7 +199,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -215,7 +215,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -228,7 +228,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -247,7 +247,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -260,7 +260,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -273,7 +273,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -300,7 +300,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, diff --git a/synth.metadata b/synth.metadata index 6ec73253..5f849652 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "3dbeac0d54125b123c8dfd39c774b37473c36944", - "internalRef": "333159182" + "sha": "acd4aabf1c1e3e5bf7db0e81f323003fb317fdaa", + "internalRef": "333302099" } }, { From f5a7fb719fe45c6fc1a7afdbdb32961fad2fc9fc Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:58:53 -0700 Subject: [PATCH 13/25] chore: use gapic-generator-python 0.33.6 PiperOrigin-RevId: 333323660 Source-Author: Google APIs Source-Date: Wed Sep 23 10:41:17 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: 7e377ce8f06ced48a79b45d97eebccb8a51f1e28 Source-Link: https://github.com/googleapis/googleapis/commit/7e377ce8f06ced48a79b45d97eebccb8a51f1e28 --- google/cloud/automl_v1/__init__.py | 4 ++-- synth.metadata | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/google/cloud/automl_v1/__init__.py b/google/cloud/automl_v1/__init__.py index 6f22bb65..b5f76f81 100644 --- a/google/cloud/automl_v1/__init__.py +++ b/google/cloud/automl_v1/__init__.py @@ -104,7 +104,6 @@ __all__ = ( "AnnotationPayload", "AnnotationSpec", - "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -165,6 +164,7 @@ "OutputConfig", "PredictRequest", "PredictResponse", + "PredictionServiceClient", "TextClassificationDatasetMetadata", "TextClassificationModelMetadata", "TextExtractionAnnotation", @@ -185,5 +185,5 @@ "UndeployModelRequest", "UpdateDatasetRequest", "UpdateModelRequest", - "PredictionServiceClient", + "AutoMlClient", ) diff --git a/synth.metadata b/synth.metadata index 5f849652..49639732 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "acd4aabf1c1e3e5bf7db0e81f323003fb317fdaa", - "internalRef": "333302099" + "sha": "7e377ce8f06ced48a79b45d97eebccb8a51f1e28", + "internalRef": "333323660" } }, { From ba7ba072c11cd76916524df688041420621ae6c1 Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 05:59:15 -0700 Subject: [PATCH 14/25] fix: naming style updates Source-Author: Mira Leung Source-Date: Wed Sep 23 16:33:18 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: 3737889dafd012d7f7f724fa04390d42db496e6c Source-Link: https://github.com/googleapis/googleapis/commit/3737889dafd012d7f7f724fa04390d42db496e6c --- docs/automl_v1beta1/services.rst | 3 + .../services/auto_ml/async_client.py | 28 +- .../automl_v1/services/auto_ml/client.py | 92 +- .../services/auto_ml/transports/base.py | 2 +- .../services/auto_ml/transports/grpc.py | 46 +- .../auto_ml/transports/grpc_asyncio.py | 51 +- .../prediction_service/async_client.py | 23 +- .../services/prediction_service/client.py | 92 +- .../prediction_service/transports/base.py | 2 +- .../prediction_service/transports/grpc.py | 46 +- .../transports/grpc_asyncio.py | 51 +- google/cloud/automl_v1beta1/__init__.py | 8 +- .../proto/annotation_payload.proto | 77 -- .../proto/annotation_spec.proto | 48 - .../automl_v1beta1/proto/classification.proto | 216 ---- .../automl_v1beta1/proto/column_spec.proto | 78 -- .../automl_v1beta1/proto/data_items.proto | 221 ---- .../automl_v1beta1/proto/data_stats.proto | 166 --- .../automl_v1beta1/proto/data_types.proto | 105 -- .../cloud/automl_v1beta1/proto/dataset.proto | 96 -- .../automl_v1beta1/proto/detection.proto | 135 -- .../cloud/automl_v1beta1/proto/geometry.proto | 46 - google/cloud/automl_v1beta1/proto/image.proto | 193 --- google/cloud/automl_v1beta1/proto/io.proto | 1132 ----------------- google/cloud/automl_v1beta1/proto/model.proto | 108 -- .../proto/model_evaluation.proto | 116 -- .../automl_v1beta1/proto/operations.proto | 189 --- .../proto/prediction_service.proto | 268 ---- .../cloud/automl_v1beta1/proto/ranges.proto | 35 - .../automl_v1beta1/proto/regression.proto | 44 - .../cloud/automl_v1beta1/proto/service.proto | 800 ------------ .../automl_v1beta1/proto/table_spec.proto | 78 -- .../cloud/automl_v1beta1/proto/tables.proto | 292 ----- .../cloud/automl_v1beta1/proto/temporal.proto | 37 - google/cloud/automl_v1beta1/proto/text.proto | 65 - .../proto/text_extraction.proto | 68 - .../automl_v1beta1/proto/text_segment.proto | 41 - .../automl_v1beta1/proto/text_sentiment.proto | 80 -- .../automl_v1beta1/proto/translation.proto | 69 - google/cloud/automl_v1beta1/proto/video.proto | 48 - .../services/auto_ml/async_client.py | 32 +- .../automl_v1beta1/services/auto_ml/client.py | 92 +- .../services/auto_ml/transports/base.py | 2 +- .../services/auto_ml/transports/grpc.py | 46 +- .../auto_ml/transports/grpc_asyncio.py | 51 +- .../prediction_service/async_client.py | 23 +- .../services/prediction_service/client.py | 92 +- .../prediction_service/transports/base.py | 2 +- .../prediction_service/transports/grpc.py | 46 +- .../transports/grpc_asyncio.py | 51 +- .../automl_v1beta1/types/classification.py | 4 +- .../cloud/automl_v1beta1/types/data_stats.py | 8 +- noxfile.py | 34 + synth.metadata | 224 +--- tests/unit/gapic/automl_v1/test_auto_ml.py | 545 ++++---- .../automl_v1/test_prediction_service.py | 496 ++++---- .../unit/gapic/automl_v1beta1/test_auto_ml.py | 603 +++++---- .../automl_v1beta1/test_prediction_service.py | 496 ++++---- 58 files changed, 1360 insertions(+), 6782 deletions(-) delete mode 100644 google/cloud/automl_v1beta1/proto/annotation_payload.proto delete mode 100644 google/cloud/automl_v1beta1/proto/annotation_spec.proto delete mode 100644 google/cloud/automl_v1beta1/proto/classification.proto delete mode 100644 google/cloud/automl_v1beta1/proto/column_spec.proto delete mode 100644 google/cloud/automl_v1beta1/proto/data_items.proto delete mode 100644 google/cloud/automl_v1beta1/proto/data_stats.proto delete mode 100644 google/cloud/automl_v1beta1/proto/data_types.proto delete mode 100644 google/cloud/automl_v1beta1/proto/dataset.proto delete mode 100644 google/cloud/automl_v1beta1/proto/detection.proto delete mode 100644 google/cloud/automl_v1beta1/proto/geometry.proto delete mode 100644 google/cloud/automl_v1beta1/proto/image.proto delete mode 100644 google/cloud/automl_v1beta1/proto/io.proto delete mode 100644 google/cloud/automl_v1beta1/proto/model.proto delete mode 100644 google/cloud/automl_v1beta1/proto/model_evaluation.proto delete mode 100644 google/cloud/automl_v1beta1/proto/operations.proto delete mode 100644 google/cloud/automl_v1beta1/proto/prediction_service.proto delete mode 100644 google/cloud/automl_v1beta1/proto/ranges.proto delete mode 100644 google/cloud/automl_v1beta1/proto/regression.proto delete mode 100644 google/cloud/automl_v1beta1/proto/service.proto delete mode 100644 google/cloud/automl_v1beta1/proto/table_spec.proto delete mode 100644 google/cloud/automl_v1beta1/proto/tables.proto delete mode 100644 google/cloud/automl_v1beta1/proto/temporal.proto delete mode 100644 google/cloud/automl_v1beta1/proto/text.proto delete mode 100644 google/cloud/automl_v1beta1/proto/text_extraction.proto delete mode 100644 google/cloud/automl_v1beta1/proto/text_segment.proto delete mode 100644 google/cloud/automl_v1beta1/proto/text_sentiment.proto delete mode 100644 google/cloud/automl_v1beta1/proto/translation.proto delete mode 100644 google/cloud/automl_v1beta1/proto/video.proto diff --git a/docs/automl_v1beta1/services.rst b/docs/automl_v1beta1/services.rst index 9fa5c54f..787e8566 100644 --- a/docs/automl_v1beta1/services.rst +++ b/docs/automl_v1beta1/services.rst @@ -7,3 +7,6 @@ Services for Google Cloud Automl v1beta1 API .. automodule:: google.cloud.automl_v1beta1.services.prediction_service :members: :inherited-members: +.. automodule:: google.cloud.automl_v1beta1.services.tables + :members: + :inherited-members: diff --git a/google/cloud/automl_v1/services/auto_ml/async_client.py b/google/cloud/automl_v1/services/auto_ml/async_client.py index 23d7b118..2b7f9c5c 100644 --- a/google/cloud/automl_v1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1/services/auto_ml/async_client.py @@ -28,8 +28,8 @@ from google.auth import credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore +from google.api_core import operation +from google.api_core import operation_async from google.cloud.automl_v1.services.auto_ml import pagers from google.cloud.automl_v1.types import annotation_spec from google.cloud.automl_v1.types import classification @@ -79,10 +79,9 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT - dataset_path = staticmethod(AutoMlClient.dataset_path) - parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) model_path = staticmethod(AutoMlClient.model_path) - parse_model_path = staticmethod(AutoMlClient.parse_model_path) + + dataset_path = staticmethod(AutoMlClient.dataset_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file @@ -113,19 +112,16 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1/services/auto_ml/client.py b/google/cloud/automl_v1/services/auto_ml/client.py index 3765ac0b..e615ce00 100644 --- a/google/cloud/automl_v1/services/auto_ml/client.py +++ b/google/cloud/automl_v1/services/auto_ml/client.py @@ -16,24 +16,22 @@ # from collections import OrderedDict -from distutils import util import os import re -from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union +from typing import Callable, Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore +import google.api_core.client_options as ClientOptions # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore +from google.api_core import operation +from google.api_core import operation_async from google.cloud.automl_v1.services.auto_ml import pagers from google.cloud.automl_v1.types import annotation_spec from google.cloud.automl_v1.types import classification @@ -198,9 +196,9 @@ def parse_model_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, - transport: Union[str, AutoMlTransport, None] = None, - client_options: Optional[client_options_lib.ClientOptions] = None, + credentials: credentials.Credentials = None, + transport: Union[str, AutoMlTransport] = None, + client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the auto ml client. @@ -214,22 +212,19 @@ def __init__( transport (Union[str, ~.AutoMlTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the - client. It won't take effect if a ``transport`` instance is provided. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -241,47 +236,29 @@ def __init__( creation failed for any reason. """ if isinstance(client_options, dict): - client_options = client_options_lib.from_dict(client_options) + client_options = ClientOptions.from_dict(client_options) if client_options is None: - client_options = client_options_lib.ClientOptions() + client_options = ClientOptions.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) - ) - - ssl_credentials = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - is_mtls = True - else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if client_options.api_endpoint is None: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT + client_options.api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT + client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT + has_client_cert_source = ( + client_options.client_cert_source is not None + or mtls.has_default_client_cert_source() + ) + client_options.api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if has_client_cert_source + else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -305,9 +282,10 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=api_endpoint, + host=client_options.api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + api_mtls_endpoint=client_options.api_endpoint, + client_cert_source=client_options.client_cert_source, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1/services/auto_ml/transports/base.py b/google/cloud/automl_v1/services/auto_ml/transports/base.py index b1e12781..5e230105 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth # type: ignore +from google import auth from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py index b957e5cd..100f50f6 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py @@ -15,7 +15,6 @@ # limitations under the License. # -import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -25,6 +24,7 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore + import grpc # type: ignore from google.cloud.automl_v1.types import annotation_spec @@ -78,7 +78,6 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -99,16 +98,14 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -131,11 +128,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -166,23 +158,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) self._stubs = {} # type: Dict[str, Callable] @@ -248,6 +223,13 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py b/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py index 0778c063..39e15a79 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py @@ -15,13 +15,11 @@ # limitations under the License. # -import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -122,7 +120,6 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -144,16 +141,14 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -176,22 +171,12 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -211,23 +196,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) # Run the base constructor. super().__init__( @@ -248,6 +216,13 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/prediction_service/async_client.py b/google/cloud/automl_v1/services/prediction_service/async_client.py index d77836a0..df141602 100644 --- a/google/cloud/automl_v1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1/services/prediction_service/async_client.py @@ -28,8 +28,8 @@ from google.auth import credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore +from google.api_core import operation +from google.api_core import operation_async from google.cloud.automl_v1.types import annotation_payload from google.cloud.automl_v1.types import data_items from google.cloud.automl_v1.types import io @@ -82,19 +82,16 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1/services/prediction_service/client.py b/google/cloud/automl_v1/services/prediction_service/client.py index d2c1971a..2ccfd9fc 100644 --- a/google/cloud/automl_v1/services/prediction_service/client.py +++ b/google/cloud/automl_v1/services/prediction_service/client.py @@ -16,24 +16,22 @@ # from collections import OrderedDict -from distutils import util import os import re -from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union +from typing import Callable, Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore +import google.api_core.client_options as ClientOptions # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore +from google.api_core import operation +from google.api_core import operation_async from google.cloud.automl_v1.types import annotation_payload from google.cloud.automl_v1.types import data_items from google.cloud.automl_v1.types import io @@ -144,9 +142,9 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, - transport: Union[str, PredictionServiceTransport, None] = None, - client_options: Optional[client_options_lib.ClientOptions] = None, + credentials: credentials.Credentials = None, + transport: Union[str, PredictionServiceTransport] = None, + client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the prediction service client. @@ -160,22 +158,19 @@ def __init__( transport (Union[str, ~.PredictionServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the - client. It won't take effect if a ``transport`` instance is provided. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -187,47 +182,29 @@ def __init__( creation failed for any reason. """ if isinstance(client_options, dict): - client_options = client_options_lib.from_dict(client_options) + client_options = ClientOptions.from_dict(client_options) if client_options is None: - client_options = client_options_lib.ClientOptions() + client_options = ClientOptions.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) - ) - - ssl_credentials = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - is_mtls = True - else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if client_options.api_endpoint is None: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT + client_options.api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT + client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT + has_client_cert_source = ( + client_options.client_cert_source is not None + or mtls.has_default_client_cert_source() + ) + client_options.api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if has_client_cert_source + else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -251,9 +228,10 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=api_endpoint, + host=client_options.api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + api_mtls_endpoint=client_options.api_endpoint, + client_cert_source=client_options.client_cert_source, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1/services/prediction_service/transports/base.py b/google/cloud/automl_v1/services/prediction_service/transports/base.py index f019a8dc..349d8793 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/base.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth # type: ignore +from google import auth from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py index 9a2c8e9b..e4508add 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py @@ -15,7 +15,6 @@ # limitations under the License. # -import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -25,6 +24,7 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore + import grpc # type: ignore from google.cloud.automl_v1.types import prediction_service @@ -61,7 +61,6 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -82,16 +81,14 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -114,11 +111,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -149,23 +141,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) self._stubs = {} # type: Dict[str, Callable] @@ -231,6 +206,13 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py b/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py index eddcb6ab..f92ad264 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py @@ -15,13 +15,11 @@ # limitations under the License. # -import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -105,7 +103,6 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -127,16 +124,14 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -159,22 +154,12 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -194,23 +179,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) # Run the base constructor. super().__init__( @@ -231,6 +199,13 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 44f619cb..904a45aa 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -17,8 +17,8 @@ from .services.auto_ml import AutoMlClient from .services.prediction_service import PredictionServiceClient -from .tables.gcs_client import GcsClient -from .tables.tables_client import TablesClient +from .services.tables.gcs_client import GcsClient +from .services.tables.tables_client import TablesClient from .types.annotation_payload import AnnotationPayload from .types.annotation_spec import AnnotationSpec from .types.classification import ClassificationAnnotation @@ -149,7 +149,6 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", - "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -228,6 +227,7 @@ "OutputConfig", "PredictRequest", "PredictResponse", + "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "PredictionServiceClient", + "AutoMlClient", ) diff --git a/google/cloud/automl_v1beta1/proto/annotation_payload.proto b/google/cloud/automl_v1beta1/proto/annotation_payload.proto deleted file mode 100644 index f62bb269..00000000 --- a/google/cloud/automl_v1beta1/proto/annotation_payload.proto +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/cloud/automl/v1beta1/detection.proto"; -import "google/cloud/automl/v1beta1/tables.proto"; -import "google/cloud/automl/v1beta1/text_extraction.proto"; -import "google/cloud/automl/v1beta1/text_sentiment.proto"; -import "google/cloud/automl/v1beta1/translation.proto"; -import "google/protobuf/any.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Contains annotation information that is relevant to AutoML. -message AnnotationPayload { - // Output only . Additional information about the annotation - // specific to the AutoML domain. - oneof detail { - // Annotation details for translation. - TranslationAnnotation translation = 2; - - // Annotation details for content or image classification. - ClassificationAnnotation classification = 3; - - // Annotation details for image object detection. - ImageObjectDetectionAnnotation image_object_detection = 4; - - // Annotation details for video classification. - // Returned for Video Classification predictions. - VideoClassificationAnnotation video_classification = 9; - - // Annotation details for video object tracking. - VideoObjectTrackingAnnotation video_object_tracking = 8; - - // Annotation details for text extraction. - TextExtractionAnnotation text_extraction = 6; - - // Annotation details for text sentiment. - TextSentimentAnnotation text_sentiment = 7; - - // Annotation details for Tables. - TablesAnnotation tables = 10; - } - - // Output only . The resource ID of the annotation spec that - // this annotation pertains to. The annotation spec comes from either an - // ancestor dataset, or the dataset that was used to train the model in use. - string annotation_spec_id = 1; - - // Output only. The value of - // [display_name][google.cloud.automl.v1beta1.AnnotationSpec.display_name] - // when the model was trained. Because this field returns a value at model - // training time, for different models trained using the same dataset, the - // returned value could be different as model owner could update the - // `display_name` between any two model training. - string display_name = 5; -} diff --git a/google/cloud/automl_v1beta1/proto/annotation_spec.proto b/google/cloud/automl_v1beta1/proto/annotation_spec.proto deleted file mode 100644 index d9df07ee..00000000 --- a/google/cloud/automl_v1beta1/proto/annotation_spec.proto +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A definition of an annotation spec. -message AnnotationSpec { - option (google.api.resource) = { - type: "automl.googleapis.com/AnnotationSpec" - pattern: "projects/{project}/locations/{location}/datasets/{dataset}/annotationSpecs/{annotation_spec}" - }; - - // Output only. Resource name of the annotation spec. - // Form: - // - // 'projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/annotationSpecs/{annotation_spec_id}' - string name = 1; - - // Required. The name of the annotation spec to show in the interface. The name can be - // up to 32 characters long and must match the regexp `[a-zA-Z0-9_]+`. - string display_name = 2; - - // Output only. The number of examples in the parent dataset - // labeled by the annotation spec. - int32 example_count = 9; -} diff --git a/google/cloud/automl_v1beta1/proto/classification.proto b/google/cloud/automl_v1beta1/proto/classification.proto deleted file mode 100644 index 0594d01e..00000000 --- a/google/cloud/automl_v1beta1/proto/classification.proto +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/temporal.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_outer_classname = "ClassificationProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Type of the classification problem. -enum ClassificationType { - // An un-set value of this enum. - CLASSIFICATION_TYPE_UNSPECIFIED = 0; - - // At most one label is allowed per example. - MULTICLASS = 1; - - // Multiple labels are allowed for one example. - MULTILABEL = 2; -} - -// Contains annotation details specific to classification. -message ClassificationAnnotation { - // Output only. A confidence estimate between 0.0 and 1.0. A higher value - // means greater confidence that the annotation is positive. If a user - // approves an annotation as negative or positive, the score value remains - // unchanged. If a user creates an annotation, the score is 0 for negative or - // 1 for positive. - float score = 1; -} - -// Contains annotation details specific to video classification. -message VideoClassificationAnnotation { - // Output only. Expresses the type of video classification. Possible values: - // - // * `segment` - Classification done on a specified by user - // time segment of a video. AnnotationSpec is answered to be present - // in that time segment, if it is present in any part of it. The video - // ML model evaluations are done only for this type of classification. - // - // * `shot`- Shot-level classification. - // AutoML Video Intelligence determines the boundaries - // for each camera shot in the entire segment of the video that user - // specified in the request configuration. AutoML Video Intelligence - // then returns labels and their confidence scores for each detected - // shot, along with the start and end time of the shot. - // WARNING: Model evaluation is not done for this classification type, - // the quality of it depends on training data, but there are no - // metrics provided to describe that quality. - // - // * `1s_interval` - AutoML Video Intelligence returns labels and their - // confidence scores for each second of the entire segment of the video - // that user specified in the request configuration. - // WARNING: Model evaluation is not done for this classification type, - // the quality of it depends on training data, but there are no - // metrics provided to describe that quality. - string type = 1; - - // Output only . The classification details of this annotation. - ClassificationAnnotation classification_annotation = 2; - - // Output only . The time segment of the video to which the - // annotation applies. - TimeSegment time_segment = 3; -} - -// Model evaluation metrics for classification problems. -// Note: For Video Classification this metrics only describe quality of the -// Video Classification predictions of "segment_classification" type. -message ClassificationEvaluationMetrics { - // Metrics for a single confidence threshold. - message ConfidenceMetricsEntry { - // Output only. Metrics are computed with an assumption that the model - // never returns predictions with score lower than this value. - float confidence_threshold = 1; - - // Output only. Metrics are computed with an assumption that the model - // always returns at most this many predictions (ordered by their score, - // descendingly), but they all still need to meet the confidence_threshold. - int32 position_threshold = 14; - - // Output only. Recall (True Positive Rate) for the given confidence - // threshold. - float recall = 2; - - // Output only. Precision for the given confidence threshold. - float precision = 3; - - // Output only. False Positive Rate for the given confidence threshold. - float false_positive_rate = 8; - - // Output only. The harmonic mean of recall and precision. - float f1_score = 4; - - // Output only. The Recall (True Positive Rate) when only considering the - // label that has the highest prediction score and not below the confidence - // threshold for each example. - float recall_at1 = 5; - - // Output only. The precision when only considering the label that has the - // highest prediction score and not below the confidence threshold for each - // example. - float precision_at1 = 6; - - // Output only. The False Positive Rate when only considering the label that - // has the highest prediction score and not below the confidence threshold - // for each example. - float false_positive_rate_at1 = 9; - - // Output only. The harmonic mean of [recall_at1][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfidenceMetricsEntry.recall_at1] and [precision_at1][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfidenceMetricsEntry.precision_at1]. - float f1_score_at1 = 7; - - // Output only. The number of model created labels that match a ground truth - // label. - int64 true_positive_count = 10; - - // Output only. The number of model created labels that do not match a - // ground truth label. - int64 false_positive_count = 11; - - // Output only. The number of ground truth labels that are not matched - // by a model created label. - int64 false_negative_count = 12; - - // Output only. The number of labels that were not created by the model, - // but if they would, they would not match a ground truth label. - int64 true_negative_count = 13; - } - - // Confusion matrix of the model running the classification. - message ConfusionMatrix { - // Output only. A row in the confusion matrix. - message Row { - // Output only. Value of the specific cell in the confusion matrix. - // The number of values each row has (i.e. the length of the row) is equal - // to the length of the `annotation_spec_id` field or, if that one is not - // populated, length of the [display_name][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfusionMatrix.display_name] field. - repeated int32 example_count = 1; - } - - // Output only. IDs of the annotation specs used in the confusion matrix. - // For Tables CLASSIFICATION - // - // [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] - // only list of [annotation_spec_display_name-s][] is populated. - repeated string annotation_spec_id = 1; - - // Output only. Display name of the annotation specs used in the confusion - // matrix, as they were at the moment of the evaluation. For Tables - // CLASSIFICATION - // - // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type], - // distinct values of the target column at the moment of the model - // evaluation are populated here. - repeated string display_name = 3; - - // Output only. Rows in the confusion matrix. The number of rows is equal to - // the size of `annotation_spec_id`. - // `row[i].example_count[j]` is the number of examples that have ground - // truth of the `annotation_spec_id[i]` and are predicted as - // `annotation_spec_id[j]` by the model being evaluated. - repeated Row row = 2; - } - - // Output only. The Area Under Precision-Recall Curve metric. Micro-averaged - // for the overall evaluation. - float au_prc = 1; - - // Output only. The Area Under Precision-Recall Curve metric based on priors. - // Micro-averaged for the overall evaluation. - // Deprecated. - float base_au_prc = 2 [deprecated = true]; - - // Output only. The Area Under Receiver Operating Characteristic curve metric. - // Micro-averaged for the overall evaluation. - float au_roc = 6; - - // Output only. The Log Loss metric. - float log_loss = 7; - - // Output only. Metrics for each confidence_threshold in - // 0.00,0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 and - // position_threshold = INT32_MAX_VALUE. - // ROC and precision-recall curves, and other aggregated metrics are derived - // from them. The confidence metrics entries may also be supplied for - // additional values of position_threshold, but from these no aggregated - // metrics are computed. - repeated ConfidenceMetricsEntry confidence_metrics_entry = 3; - - // Output only. Confusion matrix of the evaluation. - // Only set for MULTICLASS classification problems where number - // of labels is no more than 10. - // Only set for model level evaluation, not for evaluation per label. - ConfusionMatrix confusion_matrix = 4; - - // Output only. The annotation spec ids used for this evaluation. - repeated string annotation_spec_id = 5; -} diff --git a/google/cloud/automl_v1beta1/proto/column_spec.proto b/google/cloud/automl_v1beta1/proto/column_spec.proto deleted file mode 100644 index 03389b8a..00000000 --- a/google/cloud/automl_v1beta1/proto/column_spec.proto +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/data_stats.proto"; -import "google/cloud/automl/v1beta1/data_types.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A representation of a column in a relational table. When listing them, column specs are returned in the same order in which they were -// given on import . -// Used by: -// * Tables -message ColumnSpec { - option (google.api.resource) = { - type: "automl.googleapis.com/ColumnSpec" - pattern: "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}" - }; - - // Identifies the table's column, and its correlation with the column this - // ColumnSpec describes. - message CorrelatedColumn { - // The column_spec_id of the correlated column, which belongs to the same - // table as the in-context column. - string column_spec_id = 1; - - // Correlation between this and the in-context column. - CorrelationStats correlation_stats = 2; - } - - // Output only. The resource name of the column specs. - // Form: - // - // `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/tableSpecs/{table_spec_id}/columnSpecs/{column_spec_id}` - string name = 1; - - // The data type of elements stored in the column. - DataType data_type = 2; - - // Output only. The name of the column to show in the interface. The name can - // be up to 100 characters long and can consist only of ASCII Latin letters - // A-Z and a-z, ASCII digits 0-9, underscores(_), and forward slashes(/), and - // must start with a letter or a digit. - string display_name = 3; - - // Output only. Stats of the series of values in the column. - // This field may be stale, see the ancestor's - // Dataset.tables_dataset_metadata.stats_update_time field - // for the timestamp at which these stats were last updated. - DataStats data_stats = 4; - - // Deprecated. - repeated CorrelatedColumn top_correlated_columns = 5; - - // Used to perform consistent read-modify-write updates. If not set, a blind - // "overwrite" update happens. - string etag = 6; -} diff --git a/google/cloud/automl_v1beta1/proto/data_items.proto b/google/cloud/automl_v1beta1/proto/data_items.proto deleted file mode 100644 index 9b9187ad..00000000 --- a/google/cloud/automl_v1beta1/proto/data_items.proto +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/geometry.proto"; -import "google/cloud/automl/v1beta1/io.proto"; -import "google/cloud/automl/v1beta1/temporal.proto"; -import "google/cloud/automl/v1beta1/text_segment.proto"; -import "google/protobuf/any.proto"; -import "google/protobuf/duration.proto"; -import "google/protobuf/struct.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A representation of an image. -// Only images up to 30MB in size are supported. -message Image { - // Input only. The data representing the image. - // For Predict calls [image_bytes][google.cloud.automl.v1beta1.Image.image_bytes] must be set, as other options are not - // currently supported by prediction API. You can read the contents of an - // uploaded image by using the [content_uri][google.cloud.automl.v1beta1.Image.content_uri] field. - oneof data { - // Image content represented as a stream of bytes. - // Note: As with all `bytes` fields, protobuffers use a pure binary - // representation, whereas JSON representations use base64. - bytes image_bytes = 1; - - // An input config specifying the content of the image. - InputConfig input_config = 6; - } - - // Output only. HTTP URI to the thumbnail image. - string thumbnail_uri = 4; -} - -// A representation of a text snippet. -message TextSnippet { - // Required. The content of the text snippet as a string. Up to 250000 - // characters long. - string content = 1; - - // Optional. The format of [content][google.cloud.automl.v1beta1.TextSnippet.content]. Currently the only two allowed - // values are "text/html" and "text/plain". If left blank, the format is - // automatically determined from the type of the uploaded [content][google.cloud.automl.v1beta1.TextSnippet.content]. - string mime_type = 2; - - // Output only. HTTP URI where you can download the content. - string content_uri = 4; -} - -// Message that describes dimension of a document. -message DocumentDimensions { - // Unit of the document dimension. - enum DocumentDimensionUnit { - // Should not be used. - DOCUMENT_DIMENSION_UNIT_UNSPECIFIED = 0; - - // Document dimension is measured in inches. - INCH = 1; - - // Document dimension is measured in centimeters. - CENTIMETER = 2; - - // Document dimension is measured in points. 72 points = 1 inch. - POINT = 3; - } - - // Unit of the dimension. - DocumentDimensionUnit unit = 1; - - // Width value of the document, works together with the unit. - float width = 2; - - // Height value of the document, works together with the unit. - float height = 3; -} - -// A structured text document e.g. a PDF. -message Document { - // Describes the layout information of a [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the document. - message Layout { - // The type of TextSegment in the context of the original document. - enum TextSegmentType { - // Should not be used. - TEXT_SEGMENT_TYPE_UNSPECIFIED = 0; - - // The text segment is a token. e.g. word. - TOKEN = 1; - - // The text segment is a paragraph. - PARAGRAPH = 2; - - // The text segment is a form field. - FORM_FIELD = 3; - - // The text segment is the name part of a form field. It will be treated - // as child of another FORM_FIELD TextSegment if its span is subspan of - // another TextSegment with type FORM_FIELD. - FORM_FIELD_NAME = 4; - - // The text segment is the text content part of a form field. It will be - // treated as child of another FORM_FIELD TextSegment if its span is - // subspan of another TextSegment with type FORM_FIELD. - FORM_FIELD_CONTENTS = 5; - - // The text segment is a whole table, including headers, and all rows. - TABLE = 6; - - // The text segment is a table's headers. It will be treated as child of - // another TABLE TextSegment if its span is subspan of another TextSegment - // with type TABLE. - TABLE_HEADER = 7; - - // The text segment is a row in table. It will be treated as child of - // another TABLE TextSegment if its span is subspan of another TextSegment - // with type TABLE. - TABLE_ROW = 8; - - // The text segment is a cell in table. It will be treated as child of - // another TABLE_ROW TextSegment if its span is subspan of another - // TextSegment with type TABLE_ROW. - TABLE_CELL = 9; - } - - // Text Segment that represents a segment in - // [document_text][google.cloud.automl.v1beta1.Document.document_text]. - TextSegment text_segment = 1; - - // Page number of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the original document, starts - // from 1. - int32 page_number = 2; - - // The position of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the page. - // Contains exactly 4 - // - // [normalized_vertices][google.cloud.automl.v1beta1.BoundingPoly.normalized_vertices] - // and they are connected by edges in the order provided, which will - // represent a rectangle parallel to the frame. The - // [NormalizedVertex-s][google.cloud.automl.v1beta1.NormalizedVertex] are - // relative to the page. - // Coordinates are based on top-left as point (0,0). - BoundingPoly bounding_poly = 3; - - // The type of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in document. - TextSegmentType text_segment_type = 4; - } - - // An input config specifying the content of the document. - DocumentInputConfig input_config = 1; - - // The plain text version of this document. - TextSnippet document_text = 2; - - // Describes the layout of the document. - // Sorted by [page_number][]. - repeated Layout layout = 3; - - // The dimensions of the page in the document. - DocumentDimensions document_dimensions = 4; - - // Number of pages in the document. - int32 page_count = 5; -} - -// A representation of a row in a relational table. -message Row { - // The resource IDs of the column specs describing the columns of the row. - // If set must contain, but possibly in a different order, all input - // feature - // - // [column_spec_ids][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] - // of the Model this row is being passed to. - // Note: The below `values` field must match order of this field, if this - // field is set. - repeated string column_spec_ids = 2; - - // Required. The values of the row cells, given in the same order as the - // column_spec_ids, or, if not set, then in the same order as input - // feature - // - // [column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] - // of the Model this row is being passed to. - repeated google.protobuf.Value values = 3; -} - -// Example data used for training or prediction. -message ExamplePayload { - // Required. Input only. The example data. - oneof payload { - // Example image. - Image image = 1; - - // Example text. - TextSnippet text_snippet = 2; - - // Example document. - Document document = 4; - - // Example relational table row. - Row row = 3; - } -} diff --git a/google/cloud/automl_v1beta1/proto/data_stats.proto b/google/cloud/automl_v1beta1/proto/data_stats.proto deleted file mode 100644 index c13a5d45..00000000 --- a/google/cloud/automl_v1beta1/proto/data_stats.proto +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// The data statistics of a series of values that share the same DataType. -message DataStats { - // The data statistics specific to a DataType. - oneof stats { - // The statistics for FLOAT64 DataType. - Float64Stats float64_stats = 3; - - // The statistics for STRING DataType. - StringStats string_stats = 4; - - // The statistics for TIMESTAMP DataType. - TimestampStats timestamp_stats = 5; - - // The statistics for ARRAY DataType. - ArrayStats array_stats = 6; - - // The statistics for STRUCT DataType. - StructStats struct_stats = 7; - - // The statistics for CATEGORY DataType. - CategoryStats category_stats = 8; - } - - // The number of distinct values. - int64 distinct_value_count = 1; - - // The number of values that are null. - int64 null_value_count = 2; - - // The number of values that are valid. - int64 valid_value_count = 9; -} - -// The data statistics of a series of FLOAT64 values. -message Float64Stats { - // A bucket of a histogram. - message HistogramBucket { - // The minimum value of the bucket, inclusive. - double min = 1; - - // The maximum value of the bucket, exclusive unless max = `"Infinity"`, in - // which case it's inclusive. - double max = 2; - - // The number of data values that are in the bucket, i.e. are between - // min and max values. - int64 count = 3; - } - - // The mean of the series. - double mean = 1; - - // The standard deviation of the series. - double standard_deviation = 2; - - // Ordered from 0 to k k-quantile values of the data series of n values. - // The value at index i is, approximately, the i*n/k-th smallest value in the - // series; for i = 0 and i = k these are, respectively, the min and max - // values. - repeated double quantiles = 3; - - // Histogram buckets of the data series. Sorted by the min value of the - // bucket, ascendingly, and the number of the buckets is dynamically - // generated. The buckets are non-overlapping and completely cover whole - // FLOAT64 range with min of first bucket being `"-Infinity"`, and max of - // the last one being `"Infinity"`. - repeated HistogramBucket histogram_buckets = 4; -} - -// The data statistics of a series of STRING values. -message StringStats { - // The statistics of a unigram. - message UnigramStats { - // The unigram. - string value = 1; - - // The number of occurrences of this unigram in the series. - int64 count = 2; - } - - // The statistics of the top 20 unigrams, ordered by - // [count][google.cloud.automl.v1beta1.StringStats.UnigramStats.count]. - repeated UnigramStats top_unigram_stats = 1; -} - -// The data statistics of a series of TIMESTAMP values. -message TimestampStats { - // Stats split by a defined in context granularity. - message GranularStats { - // A map from granularity key to example count for that key. - // E.g. for hour_of_day `13` means 1pm, or for month_of_year `5` means May). - map buckets = 1; - } - - // The string key is the pre-defined granularity. Currently supported: - // hour_of_day, day_of_week, month_of_year. - // Granularities finer that the granularity of timestamp data are not - // populated (e.g. if timestamps are at day granularity, then hour_of_day - // is not populated). - map granular_stats = 1; -} - -// The data statistics of a series of ARRAY values. -message ArrayStats { - // Stats of all the values of all arrays, as if they were a single long - // series of data. The type depends on the element type of the array. - DataStats member_stats = 2; -} - -// The data statistics of a series of STRUCT values. -message StructStats { - // Map from a field name of the struct to data stats aggregated over series - // of all data in that field across all the structs. - map field_stats = 1; -} - -// The data statistics of a series of CATEGORY values. -message CategoryStats { - // The statistics of a single CATEGORY value. - message SingleCategoryStats { - // The CATEGORY value. - string value = 1; - - // The number of occurrences of this value in the series. - int64 count = 2; - } - - // The statistics of the top 20 CATEGORY values, ordered by - // - // [count][google.cloud.automl.v1beta1.CategoryStats.SingleCategoryStats.count]. - repeated SingleCategoryStats top_category_stats = 1; -} - -// A correlation statistics between two series of DataType values. The series -// may have differing DataType-s, but within a single series the DataType must -// be the same. -message CorrelationStats { - // The correlation value using the Cramer's V measure. - double cramers_v = 1; -} diff --git a/google/cloud/automl_v1beta1/proto/data_types.proto b/google/cloud/automl_v1beta1/proto/data_types.proto deleted file mode 100644 index 6f77f56b..00000000 --- a/google/cloud/automl_v1beta1/proto/data_types.proto +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// `TypeCode` is used as a part of -// [DataType][google.cloud.automl.v1beta1.DataType]. -enum TypeCode { - // Not specified. Should not be used. - TYPE_CODE_UNSPECIFIED = 0; - - // Encoded as `number`, or the strings `"NaN"`, `"Infinity"`, or - // `"-Infinity"`. - FLOAT64 = 3; - - // Must be between 0AD and 9999AD. Encoded as `string` according to - // [time_format][google.cloud.automl.v1beta1.DataType.time_format], or, if - // that format is not set, then in RFC 3339 `date-time` format, where - // `time-offset` = `"Z"` (e.g. 1985-04-12T23:20:50.52Z). - TIMESTAMP = 4; - - // Encoded as `string`. - STRING = 6; - - // Encoded as `list`, where the list elements are represented according to - // - // [list_element_type][google.cloud.automl.v1beta1.DataType.list_element_type]. - ARRAY = 8; - - // Encoded as `struct`, where field values are represented according to - // [struct_type][google.cloud.automl.v1beta1.DataType.struct_type]. - STRUCT = 9; - - // Values of this type are not further understood by AutoML, - // e.g. AutoML is unable to tell the order of values (as it could with - // FLOAT64), or is unable to say if one value contains another (as it - // could with STRING). - // Encoded as `string` (bytes should be base64-encoded, as described in RFC - // 4648, section 4). - CATEGORY = 10; -} - -// Indicated the type of data that can be stored in a structured data entity -// (e.g. a table). -message DataType { - // Details of DataType-s that need additional specification. - oneof details { - // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [ARRAY][google.cloud.automl.v1beta1.TypeCode.ARRAY], - // then `list_element_type` is the type of the elements. - DataType list_element_type = 2; - - // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [STRUCT][google.cloud.automl.v1beta1.TypeCode.STRUCT], then `struct_type` - // provides type information for the struct's fields. - StructType struct_type = 3; - - // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [TIMESTAMP][google.cloud.automl.v1beta1.TypeCode.TIMESTAMP] - // then `time_format` provides the format in which that time field is - // expressed. The time_format must either be one of: - // * `UNIX_SECONDS` - // * `UNIX_MILLISECONDS` - // * `UNIX_MICROSECONDS` - // * `UNIX_NANOSECONDS` - // (for respectively number of seconds, milliseconds, microseconds and - // nanoseconds since start of the Unix epoch); - // or be written in `strftime` syntax. If time_format is not set, then the - // default format as described on the type_code is used. - string time_format = 5; - } - - // Required. The [TypeCode][google.cloud.automl.v1beta1.TypeCode] for this type. - TypeCode type_code = 1; - - // If true, this DataType can also be `NULL`. In .CSV files `NULL` value is - // expressed as an empty string. - bool nullable = 4; -} - -// `StructType` defines the DataType-s of a [STRUCT][google.cloud.automl.v1beta1.TypeCode.STRUCT] type. -message StructType { - // Unordered map of struct field names to their data types. - // Fields cannot be added or removed via Update. Their names and - // data types are still mutable. - map fields = 1; -} diff --git a/google/cloud/automl_v1beta1/proto/dataset.proto b/google/cloud/automl_v1beta1/proto/dataset.proto deleted file mode 100644 index 8d1b8d93..00000000 --- a/google/cloud/automl_v1beta1/proto/dataset.proto +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/image.proto"; -import "google/cloud/automl/v1beta1/tables.proto"; -import "google/cloud/automl/v1beta1/text.proto"; -import "google/cloud/automl/v1beta1/translation.proto"; -import "google/cloud/automl/v1beta1/video.proto"; -import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A workspace for solving a single, particular machine learning (ML) problem. -// A workspace contains examples that may be annotated. -message Dataset { - option (google.api.resource) = { - type: "automl.googleapis.com/Dataset" - pattern: "projects/{project}/locations/{location}/datasets/{dataset}" - }; - - // Required. - // The dataset metadata that is specific to the problem type. - oneof dataset_metadata { - // Metadata for a dataset used for translation. - TranslationDatasetMetadata translation_dataset_metadata = 23; - - // Metadata for a dataset used for image classification. - ImageClassificationDatasetMetadata image_classification_dataset_metadata = 24; - - // Metadata for a dataset used for text classification. - TextClassificationDatasetMetadata text_classification_dataset_metadata = 25; - - // Metadata for a dataset used for image object detection. - ImageObjectDetectionDatasetMetadata image_object_detection_dataset_metadata = 26; - - // Metadata for a dataset used for video classification. - VideoClassificationDatasetMetadata video_classification_dataset_metadata = 31; - - // Metadata for a dataset used for video object tracking. - VideoObjectTrackingDatasetMetadata video_object_tracking_dataset_metadata = 29; - - // Metadata for a dataset used for text extraction. - TextExtractionDatasetMetadata text_extraction_dataset_metadata = 28; - - // Metadata for a dataset used for text sentiment. - TextSentimentDatasetMetadata text_sentiment_dataset_metadata = 30; - - // Metadata for a dataset used for Tables. - TablesDatasetMetadata tables_dataset_metadata = 33; - } - - // Output only. The resource name of the dataset. - // Form: `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}` - string name = 1; - - // Required. The name of the dataset to show in the interface. The name can be - // up to 32 characters long and can consist only of ASCII Latin letters A-Z - // and a-z, underscores - // (_), and ASCII digits 0-9. - string display_name = 2; - - // User-provided description of the dataset. The description can be up to - // 25000 characters long. - string description = 3; - - // Output only. The number of examples in the dataset. - int32 example_count = 21; - - // Output only. Timestamp when this dataset was created. - google.protobuf.Timestamp create_time = 14; - - // Used to perform consistent read-modify-write updates. If not set, a blind - // "overwrite" update happens. - string etag = 17; -} diff --git a/google/cloud/automl_v1beta1/proto/detection.proto b/google/cloud/automl_v1beta1/proto/detection.proto deleted file mode 100644 index c5864e20..00000000 --- a/google/cloud/automl_v1beta1/proto/detection.proto +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/geometry.proto"; -import "google/protobuf/duration.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Annotation details for image object detection. -message ImageObjectDetectionAnnotation { - // Output only. The rectangle representing the object location. - BoundingPoly bounding_box = 1; - - // Output only. The confidence that this annotation is positive for the parent example, - // value in [0, 1], higher means higher positivity confidence. - float score = 2; -} - -// Annotation details for video object tracking. -message VideoObjectTrackingAnnotation { - // Optional. The instance of the object, expressed as a positive integer. Used to tell - // apart objects of the same type (i.e. AnnotationSpec) when multiple are - // present on a single example. - // NOTE: Instance ID prediction quality is not a part of model evaluation and - // is done as best effort. Especially in cases when an entity goes - // off-screen for a longer time (minutes), when it comes back it may be given - // a new instance ID. - string instance_id = 1; - - // Required. A time (frame) of a video to which this annotation pertains. - // Represented as the duration since the video's start. - google.protobuf.Duration time_offset = 2; - - // Required. The rectangle representing the object location on the frame (i.e. - // at the time_offset of the video). - BoundingPoly bounding_box = 3; - - // Output only. The confidence that this annotation is positive for the video at - // the time_offset, value in [0, 1], higher means higher positivity - // confidence. For annotations created by the user the score is 1. When - // user approves an annotation, the original float score is kept (and not - // changed to 1). - float score = 4; -} - -// Bounding box matching model metrics for a single intersection-over-union -// threshold and multiple label match confidence thresholds. -message BoundingBoxMetricsEntry { - // Metrics for a single confidence threshold. - message ConfidenceMetricsEntry { - // Output only. The confidence threshold value used to compute the metrics. - float confidence_threshold = 1; - - // Output only. Recall under the given confidence threshold. - float recall = 2; - - // Output only. Precision under the given confidence threshold. - float precision = 3; - - // Output only. The harmonic mean of recall and precision. - float f1_score = 4; - } - - // Output only. The intersection-over-union threshold value used to compute - // this metrics entry. - float iou_threshold = 1; - - // Output only. The mean average precision, most often close to au_prc. - float mean_average_precision = 2; - - // Output only. Metrics for each label-match confidence_threshold from - // 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99. Precision-recall curve is - // derived from them. - repeated ConfidenceMetricsEntry confidence_metrics_entries = 3; -} - -// Model evaluation metrics for image object detection problems. -// Evaluates prediction quality of labeled bounding boxes. -message ImageObjectDetectionEvaluationMetrics { - // Output only. The total number of bounding boxes (i.e. summed over all - // images) the ground truth used to create this evaluation had. - int32 evaluated_bounding_box_count = 1; - - // Output only. The bounding boxes match metrics for each - // Intersection-over-union threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 - // and each label confidence threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 - // pair. - repeated BoundingBoxMetricsEntry bounding_box_metrics_entries = 2; - - // Output only. The single metric for bounding boxes evaluation: - // the mean_average_precision averaged over all bounding_box_metrics_entries. - float bounding_box_mean_average_precision = 3; -} - -// Model evaluation metrics for video object tracking problems. -// Evaluates prediction quality of both labeled bounding boxes and labeled -// tracks (i.e. series of bounding boxes sharing same label and instance ID). -message VideoObjectTrackingEvaluationMetrics { - // Output only. The number of video frames used to create this evaluation. - int32 evaluated_frame_count = 1; - - // Output only. The total number of bounding boxes (i.e. summed over all - // frames) the ground truth used to create this evaluation had. - int32 evaluated_bounding_box_count = 2; - - // Output only. The bounding boxes match metrics for each - // Intersection-over-union threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 - // and each label confidence threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 - // pair. - repeated BoundingBoxMetricsEntry bounding_box_metrics_entries = 4; - - // Output only. The single metric for bounding boxes evaluation: - // the mean_average_precision averaged over all bounding_box_metrics_entries. - float bounding_box_mean_average_precision = 6; -} diff --git a/google/cloud/automl_v1beta1/proto/geometry.proto b/google/cloud/automl_v1beta1/proto/geometry.proto deleted file mode 100644 index d5654aac..00000000 --- a/google/cloud/automl_v1beta1/proto/geometry.proto +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A vertex represents a 2D point in the image. -// The normalized vertex coordinates are between 0 to 1 fractions relative to -// the original plane (image, video). E.g. if the plane (e.g. whole image) would -// have size 10 x 20 then a point with normalized coordinates (0.1, 0.3) would -// be at the position (1, 6) on that plane. -message NormalizedVertex { - // Required. Horizontal coordinate. - float x = 1; - - // Required. Vertical coordinate. - float y = 2; -} - -// A bounding polygon of a detected object on a plane. -// On output both vertices and normalized_vertices are provided. -// The polygon is formed by connecting vertices in the order they are listed. -message BoundingPoly { - // Output only . The bounding polygon normalized vertices. - repeated NormalizedVertex normalized_vertices = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/image.proto b/google/cloud/automl_v1beta1/proto/image.proto deleted file mode 100644 index 960eaeb0..00000000 --- a/google/cloud/automl_v1beta1/proto/image.proto +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/annotation_spec.proto"; -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "ImageProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Dataset metadata that is specific to image classification. -message ImageClassificationDatasetMetadata { - // Required. Type of the classification problem. - ClassificationType classification_type = 1; -} - -// Dataset metadata specific to image object detection. -message ImageObjectDetectionDatasetMetadata { - -} - -// Model metadata for image classification. -message ImageClassificationModelMetadata { - // Optional. The ID of the `base` model. If it is specified, the new model - // will be created based on the `base` model. Otherwise, the new model will be - // created from scratch. The `base` model must be in the same - // `project` and `location` as the new model to create, and have the same - // `model_type`. - string base_model_id = 1; - - // Required. The train budget of creating this model, expressed in hours. The - // actual `train_cost` will be equal or less than this value. - int64 train_budget = 2; - - // Output only. The actual train cost of creating this model, expressed in - // hours. If this model is created from a `base` model, the train cost used - // to create the `base` model are not included. - int64 train_cost = 3; - - // Output only. The reason that this create model operation stopped, - // e.g. `BUDGET_REACHED`, `MODEL_CONVERGED`. - string stop_reason = 5; - - // Optional. Type of the model. The available values are: - // * `cloud` - Model to be used via prediction calls to AutoML API. - // This is the default value. - // * `mobile-low-latency-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device - // with TensorFlow afterwards. Expected to have low latency, but - // may have lower prediction quality than other models. - // * `mobile-versatile-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device - // with TensorFlow afterwards. - // * `mobile-high-accuracy-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device - // with TensorFlow afterwards. Expected to have a higher - // latency, but should also have a higher prediction quality - // than other models. - // * `mobile-core-ml-low-latency-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with Core - // ML afterwards. Expected to have low latency, but may have - // lower prediction quality than other models. - // * `mobile-core-ml-versatile-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with Core - // ML afterwards. - // * `mobile-core-ml-high-accuracy-1` - A model that, in addition to - // providing prediction via AutoML API, can also be exported - // (see [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with - // Core ML afterwards. Expected to have a higher latency, but - // should also have a higher prediction quality than other - // models. - string model_type = 7; - - // Output only. An approximate number of online prediction QPS that can - // be supported by this model per each node on which it is deployed. - double node_qps = 13; - - // Output only. The number of nodes this model is deployed on. A node is an - // abstraction of a machine resource, which can handle online prediction QPS - // as given in the node_qps field. - int64 node_count = 14; -} - -// Model metadata specific to image object detection. -message ImageObjectDetectionModelMetadata { - // Optional. Type of the model. The available values are: - // * `cloud-high-accuracy-1` - (default) A model to be used via prediction - // calls to AutoML API. Expected to have a higher latency, but - // should also have a higher prediction quality than other - // models. - // * `cloud-low-latency-1` - A model to be used via prediction - // calls to AutoML API. Expected to have low latency, but may - // have lower prediction quality than other models. - // * `mobile-low-latency-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device - // with TensorFlow afterwards. Expected to have low latency, but - // may have lower prediction quality than other models. - // * `mobile-versatile-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device - // with TensorFlow afterwards. - // * `mobile-high-accuracy-1` - A model that, in addition to providing - // prediction via AutoML API, can also be exported (see - // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device - // with TensorFlow afterwards. Expected to have a higher - // latency, but should also have a higher prediction quality - // than other models. - string model_type = 1; - - // Output only. The number of nodes this model is deployed on. A node is an - // abstraction of a machine resource, which can handle online prediction QPS - // as given in the qps_per_node field. - int64 node_count = 3; - - // Output only. An approximate number of online prediction QPS that can - // be supported by this model per each node on which it is deployed. - double node_qps = 4; - - // Output only. The reason that this create model operation stopped, - // e.g. `BUDGET_REACHED`, `MODEL_CONVERGED`. - string stop_reason = 5; - - // The train budget of creating this model, expressed in milli node - // hours i.e. 1,000 value in this field means 1 node hour. The actual - // `train_cost` will be equal or less than this value. If further model - // training ceases to provide any improvements, it will stop without using - // full budget and the stop_reason will be `MODEL_CONVERGED`. - // Note, node_hour = actual_hour * number_of_nodes_invovled. - // For model type `cloud-high-accuracy-1`(default) and `cloud-low-latency-1`, - // the train budget must be between 20,000 and 900,000 milli node hours, - // inclusive. The default value is 216, 000 which represents one day in - // wall time. - // For model type `mobile-low-latency-1`, `mobile-versatile-1`, - // `mobile-high-accuracy-1`, `mobile-core-ml-low-latency-1`, - // `mobile-core-ml-versatile-1`, `mobile-core-ml-high-accuracy-1`, the train - // budget must be between 1,000 and 100,000 milli node hours, inclusive. - // The default value is 24, 000 which represents one day in wall time. - int64 train_budget_milli_node_hours = 6; - - // Output only. The actual train cost of creating this model, expressed in - // milli node hours, i.e. 1,000 value in this field means 1 node hour. - // Guaranteed to not exceed the train budget. - int64 train_cost_milli_node_hours = 7; -} - -// Model deployment metadata specific to Image Classification. -message ImageClassificationModelDeploymentMetadata { - // Input only. The number of nodes to deploy the model on. A node is an - // abstraction of a machine resource, which can handle online prediction QPS - // as given in the model's - // - // [node_qps][google.cloud.automl.v1beta1.ImageClassificationModelMetadata.node_qps]. - // Must be between 1 and 100, inclusive on both ends. - int64 node_count = 1; -} - -// Model deployment metadata specific to Image Object Detection. -message ImageObjectDetectionModelDeploymentMetadata { - // Input only. The number of nodes to deploy the model on. A node is an - // abstraction of a machine resource, which can handle online prediction QPS - // as given in the model's - // - // [qps_per_node][google.cloud.automl.v1beta1.ImageObjectDetectionModelMetadata.qps_per_node]. - // Must be between 1 and 100, inclusive on both ends. - int64 node_count = 1; -} diff --git a/google/cloud/automl_v1beta1/proto/io.proto b/google/cloud/automl_v1beta1/proto/io.proto deleted file mode 100644 index a9979383..00000000 --- a/google/cloud/automl_v1beta1/proto/io.proto +++ /dev/null @@ -1,1132 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Input configuration for ImportData Action. -// -// The format of input depends on dataset_metadata the Dataset into which -// the import is happening has. As input source the -// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] -// is expected, unless specified otherwise. Additionally any input .CSV file -// by itself must be 100MB or smaller, unless specified otherwise. -// If an "example" file (that is, image, video etc.) with identical content -// (even if it had different GCS_FILE_PATH) is mentioned multiple times, then -// its label, bounding boxes etc. are appended. The same file should be always -// provided with the same ML_USE and GCS_FILE_PATH, if it is not, then -// these values are nondeterministically selected from the given ones. -// -// The formats are represented in EBNF with commas being literal and with -// non-terminal symbols defined near the end of this comment. The formats are: -// -// * For Image Classification: -// CSV file(s) with each line in format: -// ML_USE,GCS_FILE_PATH,LABEL,LABEL,... -// GCS_FILE_PATH leads to image of up to 30MB in size. Supported -// extensions: .JPEG, .GIF, .PNG, .WEBP, .BMP, .TIFF, .ICO -// For MULTICLASS classification type, at most one LABEL is allowed -// per image. If an image has not yet been labeled, then it should be -// mentioned just once with no LABEL. -// Some sample rows: -// TRAIN,gs://folder/image1.jpg,daisy -// TEST,gs://folder/image2.jpg,dandelion,tulip,rose -// UNASSIGNED,gs://folder/image3.jpg,daisy -// UNASSIGNED,gs://folder/image4.jpg -// -// * For Image Object Detection: -// CSV file(s) with each line in format: -// ML_USE,GCS_FILE_PATH,(LABEL,BOUNDING_BOX | ,,,,,,,) -// GCS_FILE_PATH leads to image of up to 30MB in size. Supported -// extensions: .JPEG, .GIF, .PNG. -// Each image is assumed to be exhaustively labeled. The minimum -// allowed BOUNDING_BOX edge length is 0.01, and no more than 500 -// BOUNDING_BOX-es per image are allowed (one BOUNDING_BOX is defined -// per line). If an image has not yet been labeled, then it should be -// mentioned just once with no LABEL and the ",,,,,,," in place of the -// BOUNDING_BOX. For images which are known to not contain any -// bounding boxes, they should be labelled explictly as -// "NEGATIVE_IMAGE", followed by ",,,,,,," in place of the -// BOUNDING_BOX. -// Sample rows: -// TRAIN,gs://folder/image1.png,car,0.1,0.1,,,0.3,0.3,, -// TRAIN,gs://folder/image1.png,bike,.7,.6,,,.8,.9,, -// UNASSIGNED,gs://folder/im2.png,car,0.1,0.1,0.2,0.1,0.2,0.3,0.1,0.3 -// TEST,gs://folder/im3.png,,,,,,,,, -// TRAIN,gs://folder/im4.png,NEGATIVE_IMAGE,,,,,,,,, -// -// * For Video Classification: -// CSV file(s) with each line in format: -// ML_USE,GCS_FILE_PATH -// where ML_USE VALIDATE value should not be used. The GCS_FILE_PATH -// should lead to another .csv file which describes examples that have -// given ML_USE, using the following row format: -// GCS_FILE_PATH,(LABEL,TIME_SEGMENT_START,TIME_SEGMENT_END | ,,) -// Here GCS_FILE_PATH leads to a video of up to 50GB in size and up -// to 3h duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. -// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the -// length of the video, and end has to be after the start. Any segment -// of a video which has one or more labels on it, is considered a -// hard negative for all other labels. Any segment with no labels on -// it is considered to be unknown. If a whole video is unknown, then -// it shuold be mentioned just once with ",," in place of LABEL, -// TIME_SEGMENT_START,TIME_SEGMENT_END. -// Sample top level CSV file: -// TRAIN,gs://folder/train_videos.csv -// TEST,gs://folder/test_videos.csv -// UNASSIGNED,gs://folder/other_videos.csv -// Sample rows of a CSV file for a particular ML_USE: -// gs://folder/video1.avi,car,120,180.000021 -// gs://folder/video1.avi,bike,150,180.000021 -// gs://folder/vid2.avi,car,0,60.5 -// gs://folder/vid3.avi,,, -// -// * For Video Object Tracking: -// CSV file(s) with each line in format: -// ML_USE,GCS_FILE_PATH -// where ML_USE VALIDATE value should not be used. The GCS_FILE_PATH -// should lead to another .csv file which describes examples that have -// given ML_USE, using one of the following row format: -// GCS_FILE_PATH,LABEL,[INSTANCE_ID],TIMESTAMP,BOUNDING_BOX -// or -// GCS_FILE_PATH,,,,,,,,,, -// Here GCS_FILE_PATH leads to a video of up to 50GB in size and up -// to 3h duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. -// Providing INSTANCE_IDs can help to obtain a better model. When -// a specific labeled entity leaves the video frame, and shows up -// afterwards it is not required, albeit preferable, that the same -// INSTANCE_ID is given to it. -// TIMESTAMP must be within the length of the video, the -// BOUNDING_BOX is assumed to be drawn on the closest video's frame -// to the TIMESTAMP. Any mentioned by the TIMESTAMP frame is expected -// to be exhaustively labeled and no more than 500 BOUNDING_BOX-es per -// frame are allowed. If a whole video is unknown, then it should be -// mentioned just once with ",,,,,,,,,," in place of LABEL, -// [INSTANCE_ID],TIMESTAMP,BOUNDING_BOX. -// Sample top level CSV file: -// TRAIN,gs://folder/train_videos.csv -// TEST,gs://folder/test_videos.csv -// UNASSIGNED,gs://folder/other_videos.csv -// Seven sample rows of a CSV file for a particular ML_USE: -// gs://folder/video1.avi,car,1,12.10,0.8,0.8,0.9,0.8,0.9,0.9,0.8,0.9 -// gs://folder/video1.avi,car,1,12.90,0.4,0.8,0.5,0.8,0.5,0.9,0.4,0.9 -// gs://folder/video1.avi,car,2,12.10,.4,.2,.5,.2,.5,.3,.4,.3 -// gs://folder/video1.avi,car,2,12.90,.8,.2,,,.9,.3,, -// gs://folder/video1.avi,bike,,12.50,.45,.45,,,.55,.55,, -// gs://folder/video2.avi,car,1,0,.1,.9,,,.9,.1,, -// gs://folder/video2.avi,,,,,,,,,,, -// * For Text Extraction: -// CSV file(s) with each line in format: -// ML_USE,GCS_FILE_PATH -// GCS_FILE_PATH leads to a .JSONL (that is, JSON Lines) file which -// either imports text in-line or as documents. Any given -// .JSONL file must be 100MB or smaller. -// The in-line .JSONL file contains, per line, a proto that wraps a -// TextSnippet proto (in json representation) followed by one or more -// AnnotationPayload protos (called annotations), which have -// display_name and text_extraction detail populated. The given text -// is expected to be annotated exhaustively, for example, if you look -// for animals and text contains "dolphin" that is not labeled, then -// "dolphin" is assumed to not be an animal. Any given text snippet -// content must be 10KB or smaller, and also be UTF-8 NFC encoded -// (ASCII already is). -// The document .JSONL file contains, per line, a proto that wraps a -// Document proto. The Document proto must have either document_text -// or input_config set. In document_text case, the Document proto may -// also contain the spatial information of the document, including -// layout, document dimension and page number. In input_config case, -// only PDF documents are supported now, and each document may be up -// to 2MB large. Currently, annotations on documents cannot be -// specified at import. -// Three sample CSV rows: -// TRAIN,gs://folder/file1.jsonl -// VALIDATE,gs://folder/file2.jsonl -// TEST,gs://folder/file3.jsonl -// Sample in-line JSON Lines file for entity extraction (presented here -// with artificial line breaks, but the only actual line break is -// denoted by \n).: -// { -// "document": { -// "document_text": {"content": "dog cat"} -// "layout": [ -// { -// "text_segment": { -// "start_offset": 0, -// "end_offset": 3, -// }, -// "page_number": 1, -// "bounding_poly": { -// "normalized_vertices": [ -// {"x": 0.1, "y": 0.1}, -// {"x": 0.1, "y": 0.3}, -// {"x": 0.3, "y": 0.3}, -// {"x": 0.3, "y": 0.1}, -// ], -// }, -// "text_segment_type": TOKEN, -// }, -// { -// "text_segment": { -// "start_offset": 4, -// "end_offset": 7, -// }, -// "page_number": 1, -// "bounding_poly": { -// "normalized_vertices": [ -// {"x": 0.4, "y": 0.1}, -// {"x": 0.4, "y": 0.3}, -// {"x": 0.8, "y": 0.3}, -// {"x": 0.8, "y": 0.1}, -// ], -// }, -// "text_segment_type": TOKEN, -// } -// -// ], -// "document_dimensions": { -// "width": 8.27, -// "height": 11.69, -// "unit": INCH, -// } -// "page_count": 1, -// }, -// "annotations": [ -// { -// "display_name": "animal", -// "text_extraction": {"text_segment": {"start_offset": 0, -// "end_offset": 3}} -// }, -// { -// "display_name": "animal", -// "text_extraction": {"text_segment": {"start_offset": 4, -// "end_offset": 7}} -// } -// ], -// }\n -// { -// "text_snippet": { -// "content": "This dog is good." -// }, -// "annotations": [ -// { -// "display_name": "animal", -// "text_extraction": { -// "text_segment": {"start_offset": 5, "end_offset": 8} -// } -// } -// ] -// } -// Sample document JSON Lines file (presented here with artificial line -// breaks, but the only actual line break is denoted by \n).: -// { -// "document": { -// "input_config": { -// "gcs_source": { "input_uris": [ "gs://folder/document1.pdf" ] -// } -// } -// } -// }\n -// { -// "document": { -// "input_config": { -// "gcs_source": { "input_uris": [ "gs://folder/document2.pdf" ] -// } -// } -// } -// } -// -// * For Text Classification: -// CSV file(s) with each line in format: -// ML_USE,(TEXT_SNIPPET | GCS_FILE_PATH),LABEL,LABEL,... -// TEXT_SNIPPET and GCS_FILE_PATH are distinguished by a pattern. If -// the column content is a valid gcs file path, i.e. prefixed by -// "gs://", it will be treated as a GCS_FILE_PATH, else if the content -// is enclosed within double quotes (""), it is -// treated as a TEXT_SNIPPET. In the GCS_FILE_PATH case, the path -// must lead to a .txt file with UTF-8 encoding, for example, -// "gs://folder/content.txt", and the content in it is extracted -// as a text snippet. In TEXT_SNIPPET case, the column content -// excluding quotes is treated as to be imported text snippet. In -// both cases, the text snippet/file size must be within 128kB. -// Maximum 100 unique labels are allowed per CSV row. -// Sample rows: -// TRAIN,"They have bad food and very rude",RudeService,BadFood -// TRAIN,gs://folder/content.txt,SlowService -// TEST,"Typically always bad service there.",RudeService -// VALIDATE,"Stomach ache to go.",BadFood -// -// * For Text Sentiment: -// CSV file(s) with each line in format: -// ML_USE,(TEXT_SNIPPET | GCS_FILE_PATH),SENTIMENT -// TEXT_SNIPPET and GCS_FILE_PATH are distinguished by a pattern. If -// the column content is a valid gcs file path, that is, prefixed by -// "gs://", it is treated as a GCS_FILE_PATH, otherwise it is treated -// as a TEXT_SNIPPET. In the GCS_FILE_PATH case, the path -// must lead to a .txt file with UTF-8 encoding, for example, -// "gs://folder/content.txt", and the content in it is extracted -// as a text snippet. In TEXT_SNIPPET case, the column content itself -// is treated as to be imported text snippet. In both cases, the -// text snippet must be up to 500 characters long. -// Sample rows: -// TRAIN,"@freewrytin this is way too good for your product",2 -// TRAIN,"I need this product so bad",3 -// TEST,"Thank you for this product.",4 -// VALIDATE,gs://folder/content.txt,2 -// -// * For Tables: -// Either -// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] or -// -// [bigquery_source][google.cloud.automl.v1beta1.InputConfig.bigquery_source] -// can be used. All inputs is concatenated into a single -// -// [primary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_name] -// For gcs_source: -// CSV file(s), where the first row of the first file is the header, -// containing unique column names. If the first row of a subsequent -// file is the same as the header, then it is also treated as a -// header. All other rows contain values for the corresponding -// columns. -// Each .CSV file by itself must be 10GB or smaller, and their total -// size must be 100GB or smaller. -// First three sample rows of a CSV file: -// "Id","First Name","Last Name","Dob","Addresses" -// -// "1","John","Doe","1968-01-22","[{"status":"current","address":"123_First_Avenue","city":"Seattle","state":"WA","zip":"11111","numberOfYears":"1"},{"status":"previous","address":"456_Main_Street","city":"Portland","state":"OR","zip":"22222","numberOfYears":"5"}]" -// -// "2","Jane","Doe","1980-10-16","[{"status":"current","address":"789_Any_Avenue","city":"Albany","state":"NY","zip":"33333","numberOfYears":"2"},{"status":"previous","address":"321_Main_Street","city":"Hoboken","state":"NJ","zip":"44444","numberOfYears":"3"}]} -// For bigquery_source: -// An URI of a BigQuery table. The user data size of the BigQuery -// table must be 100GB or smaller. -// An imported table must have between 2 and 1,000 columns, inclusive, -// and between 1000 and 100,000,000 rows, inclusive. There are at most 5 -// import data running in parallel. -// Definitions: -// ML_USE = "TRAIN" | "VALIDATE" | "TEST" | "UNASSIGNED" -// Describes how the given example (file) should be used for model -// training. "UNASSIGNED" can be used when user has no preference. -// GCS_FILE_PATH = A path to file on GCS, e.g. "gs://folder/image1.png". -// LABEL = A display name of an object on an image, video etc., e.g. "dog". -// Must be up to 32 characters long and can consist only of ASCII -// Latin letters A-Z and a-z, underscores(_), and ASCII digits 0-9. -// For each label an AnnotationSpec is created which display_name -// becomes the label; AnnotationSpecs are given back in predictions. -// INSTANCE_ID = A positive integer that identifies a specific instance of a -// labeled entity on an example. Used e.g. to track two cars on -// a video while being able to tell apart which one is which. -// BOUNDING_BOX = VERTEX,VERTEX,VERTEX,VERTEX | VERTEX,,,VERTEX,, -// A rectangle parallel to the frame of the example (image, -// video). If 4 vertices are given they are connected by edges -// in the order provided, if 2 are given they are recognized -// as diagonally opposite vertices of the rectangle. -// VERTEX = COORDINATE,COORDINATE -// First coordinate is horizontal (x), the second is vertical (y). -// COORDINATE = A float in 0 to 1 range, relative to total length of -// image or video in given dimension. For fractions the -// leading non-decimal 0 can be omitted (i.e. 0.3 = .3). -// Point 0,0 is in top left. -// TIME_SEGMENT_START = TIME_OFFSET -// Expresses a beginning, inclusive, of a time segment -// within an example that has a time dimension -// (e.g. video). -// TIME_SEGMENT_END = TIME_OFFSET -// Expresses an end, exclusive, of a time segment within -// an example that has a time dimension (e.g. video). -// TIME_OFFSET = A number of seconds as measured from the start of an -// example (e.g. video). Fractions are allowed, up to a -// microsecond precision. "inf" is allowed, and it means the end -// of the example. -// TEXT_SNIPPET = A content of a text snippet, UTF-8 encoded, enclosed within -// double quotes (""). -// SENTIMENT = An integer between 0 and -// Dataset.text_sentiment_dataset_metadata.sentiment_max -// (inclusive). Describes the ordinal of the sentiment - higher -// value means a more positive sentiment. All the values are -// completely relative, i.e. neither 0 needs to mean a negative or -// neutral sentiment nor sentiment_max needs to mean a positive one -// - it is just required that 0 is the least positive sentiment -// in the data, and sentiment_max is the most positive one. -// The SENTIMENT shouldn't be confused with "score" or "magnitude" -// from the previous Natural Language Sentiment Analysis API. -// All SENTIMENT values between 0 and sentiment_max must be -// represented in the imported data. On prediction the same 0 to -// sentiment_max range will be used. The difference between -// neighboring sentiment values needs not to be uniform, e.g. 1 and -// 2 may be similar whereas the difference between 2 and 3 may be -// huge. -// -// Errors: -// If any of the provided CSV files can't be parsed or if more than certain -// percent of CSV rows cannot be processed then the operation fails and -// nothing is imported. Regardless of overall success or failure the per-row -// failures, up to a certain count cap, is listed in -// Operation.metadata.partial_failures. -// -message InputConfig { - // The source of the input. - oneof source { - // The Google Cloud Storage location for the input content. - // In ImportData, the gcs_source points to a csv with structure described in - // the comment. - GcsSource gcs_source = 1; - - // The BigQuery location for the input content. - BigQuerySource bigquery_source = 3; - } - - // Additional domain-specific parameters describing the semantic of the - // imported data, any string must be up to 25000 - // characters long. - // - // * For Tables: - // `schema_inference_version` - (integer) Required. The version of the - // algorithm that should be used for the initial inference of the - // schema (columns' DataTypes) of the table the data is being imported - // into. Allowed values: "1". - map params = 2; -} - -// Input configuration for BatchPredict Action. -// -// The format of input depends on the ML problem of the model used for -// prediction. As input source the -// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] -// is expected, unless specified otherwise. -// -// The formats are represented in EBNF with commas being literal and with -// non-terminal symbols defined near the end of this comment. The formats -// are: -// -// * For Image Classification: -// CSV file(s) with each line having just a single column: -// GCS_FILE_PATH -// which leads to image of up to 30MB in size. Supported -// extensions: .JPEG, .GIF, .PNG. This path is treated as the ID in -// the Batch predict output. -// Three sample rows: -// gs://folder/image1.jpeg -// gs://folder/image2.gif -// gs://folder/image3.png -// -// * For Image Object Detection: -// CSV file(s) with each line having just a single column: -// GCS_FILE_PATH -// which leads to image of up to 30MB in size. Supported -// extensions: .JPEG, .GIF, .PNG. This path is treated as the ID in -// the Batch predict output. -// Three sample rows: -// gs://folder/image1.jpeg -// gs://folder/image2.gif -// gs://folder/image3.png -// * For Video Classification: -// CSV file(s) with each line in format: -// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END -// GCS_FILE_PATH leads to video of up to 50GB in size and up to 3h -// duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. -// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the -// length of the video, and end has to be after the start. -// Three sample rows: -// gs://folder/video1.mp4,10,40 -// gs://folder/video1.mp4,20,60 -// gs://folder/vid2.mov,0,inf -// -// * For Video Object Tracking: -// CSV file(s) with each line in format: -// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END -// GCS_FILE_PATH leads to video of up to 50GB in size and up to 3h -// duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. -// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the -// length of the video, and end has to be after the start. -// Three sample rows: -// gs://folder/video1.mp4,10,240 -// gs://folder/video1.mp4,300,360 -// gs://folder/vid2.mov,0,inf -// * For Text Classification: -// CSV file(s) with each line having just a single column: -// GCS_FILE_PATH | TEXT_SNIPPET -// Any given text file can have size upto 128kB. -// Any given text snippet content must have 60,000 characters or less. -// Three sample rows: -// gs://folder/text1.txt -// "Some text content to predict" -// gs://folder/text3.pdf -// Supported file extensions: .txt, .pdf -// -// * For Text Sentiment: -// CSV file(s) with each line having just a single column: -// GCS_FILE_PATH | TEXT_SNIPPET -// Any given text file can have size upto 128kB. -// Any given text snippet content must have 500 characters or less. -// Three sample rows: -// gs://folder/text1.txt -// "Some text content to predict" -// gs://folder/text3.pdf -// Supported file extensions: .txt, .pdf -// -// * For Text Extraction -// .JSONL (i.e. JSON Lines) file(s) which either provide text in-line or -// as documents (for a single BatchPredict call only one of the these -// formats may be used). -// The in-line .JSONL file(s) contain per line a proto that -// wraps a temporary user-assigned TextSnippet ID (string up to 2000 -// characters long) called "id", a TextSnippet proto (in -// json representation) and zero or more TextFeature protos. Any given -// text snippet content must have 30,000 characters or less, and also -// be UTF-8 NFC encoded (ASCII already is). The IDs provided should be -// unique. -// The document .JSONL file(s) contain, per line, a proto that wraps a -// Document proto with input_config set. Only PDF documents are -// supported now, and each document must be up to 2MB large. -// Any given .JSONL file must be 100MB or smaller, and no more than 20 -// files may be given. -// Sample in-line JSON Lines file (presented here with artificial line -// breaks, but the only actual line break is denoted by \n): -// { -// "id": "my_first_id", -// "text_snippet": { "content": "dog car cat"}, -// "text_features": [ -// { -// "text_segment": {"start_offset": 4, "end_offset": 6}, -// "structural_type": PARAGRAPH, -// "bounding_poly": { -// "normalized_vertices": [ -// {"x": 0.1, "y": 0.1}, -// {"x": 0.1, "y": 0.3}, -// {"x": 0.3, "y": 0.3}, -// {"x": 0.3, "y": 0.1}, -// ] -// }, -// } -// ], -// }\n -// { -// "id": "2", -// "text_snippet": { -// "content": "An elaborate content", -// "mime_type": "text/plain" -// } -// } -// Sample document JSON Lines file (presented here with artificial line -// breaks, but the only actual line break is denoted by \n).: -// { -// "document": { -// "input_config": { -// "gcs_source": { "input_uris": [ "gs://folder/document1.pdf" ] -// } -// } -// } -// }\n -// { -// "document": { -// "input_config": { -// "gcs_source": { "input_uris": [ "gs://folder/document2.pdf" ] -// } -// } -// } -// } -// -// * For Tables: -// Either -// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] or -// -// [bigquery_source][google.cloud.automl.v1beta1.InputConfig.bigquery_source]. -// GCS case: -// CSV file(s), each by itself 10GB or smaller and total size must be -// 100GB or smaller, where first file must have a header containing -// column names. If the first row of a subsequent file is the same as -// the header, then it is also treated as a header. All other rows -// contain values for the corresponding columns. -// The column names must contain the model's -// -// [input_feature_column_specs'][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] -// -// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] -// (order doesn't matter). The columns corresponding to the model's -// input feature column specs must contain values compatible with the -// column spec's data types. Prediction on all the rows, i.e. the CSV -// lines, will be attempted. For FORECASTING -// -// [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: -// all columns having -// -// [TIME_SERIES_AVAILABLE_PAST_ONLY][google.cloud.automl.v1beta1.ColumnSpec.ForecastingMetadata.ColumnType] -// type will be ignored. -// First three sample rows of a CSV file: -// "First Name","Last Name","Dob","Addresses" -// -// "John","Doe","1968-01-22","[{"status":"current","address":"123_First_Avenue","city":"Seattle","state":"WA","zip":"11111","numberOfYears":"1"},{"status":"previous","address":"456_Main_Street","city":"Portland","state":"OR","zip":"22222","numberOfYears":"5"}]" -// -// "Jane","Doe","1980-10-16","[{"status":"current","address":"789_Any_Avenue","city":"Albany","state":"NY","zip":"33333","numberOfYears":"2"},{"status":"previous","address":"321_Main_Street","city":"Hoboken","state":"NJ","zip":"44444","numberOfYears":"3"}]} -// BigQuery case: -// An URI of a BigQuery table. The user data size of the BigQuery -// table must be 100GB or smaller. -// The column names must contain the model's -// -// [input_feature_column_specs'][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] -// -// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] -// (order doesn't matter). The columns corresponding to the model's -// input feature column specs must contain values compatible with the -// column spec's data types. Prediction on all the rows of the table -// will be attempted. For FORECASTING -// -// [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: -// all columns having -// -// [TIME_SERIES_AVAILABLE_PAST_ONLY][google.cloud.automl.v1beta1.ColumnSpec.ForecastingMetadata.ColumnType] -// type will be ignored. -// -// Definitions: -// GCS_FILE_PATH = A path to file on GCS, e.g. "gs://folder/video.avi". -// TEXT_SNIPPET = A content of a text snippet, UTF-8 encoded, enclosed within -// double quotes ("") -// TIME_SEGMENT_START = TIME_OFFSET -// Expresses a beginning, inclusive, of a time segment -// within an -// example that has a time dimension (e.g. video). -// TIME_SEGMENT_END = TIME_OFFSET -// Expresses an end, exclusive, of a time segment within -// an example that has a time dimension (e.g. video). -// TIME_OFFSET = A number of seconds as measured from the start of an -// example (e.g. video). Fractions are allowed, up to a -// microsecond precision. "inf" is allowed and it means the end -// of the example. -// -// Errors: -// If any of the provided CSV files can't be parsed or if more than certain -// percent of CSV rows cannot be processed then the operation fails and -// prediction does not happen. Regardless of overall success or failure the -// per-row failures, up to a certain count cap, will be listed in -// Operation.metadata.partial_failures. -message BatchPredictInputConfig { - // Required. The source of the input. - oneof source { - // The Google Cloud Storage location for the input content. - GcsSource gcs_source = 1; - - // The BigQuery location for the input content. - BigQuerySource bigquery_source = 2; - } -} - -// Input configuration of a [Document][google.cloud.automl.v1beta1.Document]. -message DocumentInputConfig { - // The Google Cloud Storage location of the document file. Only a single path - // should be given. - // Max supported size: 512MB. - // Supported extensions: .PDF. - GcsSource gcs_source = 1; -} - -// * For Translation: -// CSV file `translation.csv`, with each line in format: -// ML_USE,GCS_FILE_PATH -// GCS_FILE_PATH leads to a .TSV file which describes examples that have -// given ML_USE, using the following row format per line: -// TEXT_SNIPPET (in source language) \t TEXT_SNIPPET (in target -// language) -// -// * For Tables: -// Output depends on whether the dataset was imported from GCS or -// BigQuery. -// GCS case: -// -// [gcs_destination][google.cloud.automl.v1beta1.OutputConfig.gcs_destination] -// must be set. Exported are CSV file(s) `tables_1.csv`, -// `tables_2.csv`,...,`tables_N.csv` with each having as header line -// the table's column names, and all other lines contain values for -// the header columns. -// BigQuery case: -// -// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] -// pointing to a BigQuery project must be set. In the given project a -// new dataset will be created with name -// -// `export_data__` -// where will be made -// BigQuery-dataset-name compatible (e.g. most special characters will -// become underscores), and timestamp will be in -// YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" format. In that -// dataset a new table called `primary_table` will be created, and -// filled with precisely the same data as this obtained on import. -message OutputConfig { - // Required. The destination of the output. - oneof destination { - // The Google Cloud Storage location where the output is to be written to. - // For Image Object Detection, Text Extraction, Video Classification and - // Tables, in the given directory a new directory will be created with name: - // export_data-- where - // timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format. All export - // output will be written into that directory. - GcsDestination gcs_destination = 1; - - // The BigQuery location where the output is to be written to. - BigQueryDestination bigquery_destination = 2; - } -} - -// Output configuration for BatchPredict Action. -// -// As destination the -// -// [gcs_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.gcs_destination] -// must be set unless specified otherwise for a domain. If gcs_destination is -// set then in the given directory a new directory is created. Its name -// will be -// "prediction--", -// where timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format. The contents -// of it depends on the ML problem the predictions are made for. -// -// * For Image Classification: -// In the created directory files `image_classification_1.jsonl`, -// `image_classification_2.jsonl`,...,`image_classification_N.jsonl` -// will be created, where N may be 1, and depends on the -// total number of the successfully predicted images and annotations. -// A single image will be listed only once with all its annotations, -// and its annotations will never be split across files. -// Each .JSONL file will contain, per line, a JSON representation of a -// proto that wraps image's "ID" : "" followed by a list of -// zero or more AnnotationPayload protos (called annotations), which -// have classification detail populated. -// If prediction for any image failed (partially or completely), then an -// additional `errors_1.jsonl`, `errors_2.jsonl`,..., `errors_N.jsonl` -// files will be created (N depends on total number of failed -// predictions). These files will have a JSON representation of a proto -// that wraps the same "ID" : "" but here followed by -// exactly one -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// containing only `code` and `message`fields. -// -// * For Image Object Detection: -// In the created directory files `image_object_detection_1.jsonl`, -// `image_object_detection_2.jsonl`,...,`image_object_detection_N.jsonl` -// will be created, where N may be 1, and depends on the -// total number of the successfully predicted images and annotations. -// Each .JSONL file will contain, per line, a JSON representation of a -// proto that wraps image's "ID" : "" followed by a list of -// zero or more AnnotationPayload protos (called annotations), which -// have image_object_detection detail populated. A single image will -// be listed only once with all its annotations, and its annotations -// will never be split across files. -// If prediction for any image failed (partially or completely), then -// additional `errors_1.jsonl`, `errors_2.jsonl`,..., `errors_N.jsonl` -// files will be created (N depends on total number of failed -// predictions). These files will have a JSON representation of a proto -// that wraps the same "ID" : "" but here followed by -// exactly one -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// containing only `code` and `message`fields. -// * For Video Classification: -// In the created directory a video_classification.csv file, and a .JSON -// file per each video classification requested in the input (i.e. each -// line in given CSV(s)), will be created. -// -// The format of video_classification.csv is: -// -// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END,JSON_FILE_NAME,STATUS -// where: -// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END = matches 1 to 1 -// the prediction input lines (i.e. video_classification.csv has -// precisely the same number of lines as the prediction input had.) -// JSON_FILE_NAME = Name of .JSON file in the output directory, which -// contains prediction responses for the video time segment. -// STATUS = "OK" if prediction completed successfully, or an error code -// with message otherwise. If STATUS is not "OK" then the .JSON file -// for that line may not exist or be empty. -// -// Each .JSON file, assuming STATUS is "OK", will contain a list of -// AnnotationPayload protos in JSON format, which are the predictions -// for the video time segment the file is assigned to in the -// video_classification.csv. All AnnotationPayload protos will have -// video_classification field set, and will be sorted by -// video_classification.type field (note that the returned types are -// governed by `classifaction_types` parameter in -// [PredictService.BatchPredictRequest.params][]). -// -// * For Video Object Tracking: -// In the created directory a video_object_tracking.csv file will be -// created, and multiple files video_object_trackinng_1.json, -// video_object_trackinng_2.json,..., video_object_trackinng_N.json, -// where N is the number of requests in the input (i.e. the number of -// lines in given CSV(s)). -// -// The format of video_object_tracking.csv is: -// -// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END,JSON_FILE_NAME,STATUS -// where: -// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END = matches 1 to 1 -// the prediction input lines (i.e. video_object_tracking.csv has -// precisely the same number of lines as the prediction input had.) -// JSON_FILE_NAME = Name of .JSON file in the output directory, which -// contains prediction responses for the video time segment. -// STATUS = "OK" if prediction completed successfully, or an error -// code with message otherwise. If STATUS is not "OK" then the .JSON -// file for that line may not exist or be empty. -// -// Each .JSON file, assuming STATUS is "OK", will contain a list of -// AnnotationPayload protos in JSON format, which are the predictions -// for each frame of the video time segment the file is assigned to in -// video_object_tracking.csv. All AnnotationPayload protos will have -// video_object_tracking field set. -// * For Text Classification: -// In the created directory files `text_classification_1.jsonl`, -// `text_classification_2.jsonl`,...,`text_classification_N.jsonl` -// will be created, where N may be 1, and depends on the -// total number of inputs and annotations found. -// -// Each .JSONL file will contain, per line, a JSON representation of a -// proto that wraps input text snippet or input text file and a list of -// zero or more AnnotationPayload protos (called annotations), which -// have classification detail populated. A single text snippet or file -// will be listed only once with all its annotations, and its -// annotations will never be split across files. -// -// If prediction for any text snippet or file failed (partially or -// completely), then additional `errors_1.jsonl`, `errors_2.jsonl`,..., -// `errors_N.jsonl` files will be created (N depends on total number of -// failed predictions). These files will have a JSON representation of a -// proto that wraps input text snippet or input text file followed by -// exactly one -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// containing only `code` and `message`. -// -// * For Text Sentiment: -// In the created directory files `text_sentiment_1.jsonl`, -// `text_sentiment_2.jsonl`,...,`text_sentiment_N.jsonl` -// will be created, where N may be 1, and depends on the -// total number of inputs and annotations found. -// -// Each .JSONL file will contain, per line, a JSON representation of a -// proto that wraps input text snippet or input text file and a list of -// zero or more AnnotationPayload protos (called annotations), which -// have text_sentiment detail populated. A single text snippet or file -// will be listed only once with all its annotations, and its -// annotations will never be split across files. -// -// If prediction for any text snippet or file failed (partially or -// completely), then additional `errors_1.jsonl`, `errors_2.jsonl`,..., -// `errors_N.jsonl` files will be created (N depends on total number of -// failed predictions). These files will have a JSON representation of a -// proto that wraps input text snippet or input text file followed by -// exactly one -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// containing only `code` and `message`. -// -// * For Text Extraction: -// In the created directory files `text_extraction_1.jsonl`, -// `text_extraction_2.jsonl`,...,`text_extraction_N.jsonl` -// will be created, where N may be 1, and depends on the -// total number of inputs and annotations found. -// The contents of these .JSONL file(s) depend on whether the input -// used inline text, or documents. -// If input was inline, then each .JSONL file will contain, per line, -// a JSON representation of a proto that wraps given in request text -// snippet's "id" (if specified), followed by input text snippet, -// and a list of zero or more -// AnnotationPayload protos (called annotations), which have -// text_extraction detail populated. A single text snippet will be -// listed only once with all its annotations, and its annotations will -// never be split across files. -// If input used documents, then each .JSONL file will contain, per -// line, a JSON representation of a proto that wraps given in request -// document proto, followed by its OCR-ed representation in the form -// of a text snippet, finally followed by a list of zero or more -// AnnotationPayload protos (called annotations), which have -// text_extraction detail populated and refer, via their indices, to -// the OCR-ed text snippet. A single document (and its text snippet) -// will be listed only once with all its annotations, and its -// annotations will never be split across files. -// If prediction for any text snippet failed (partially or completely), -// then additional `errors_1.jsonl`, `errors_2.jsonl`,..., -// `errors_N.jsonl` files will be created (N depends on total number of -// failed predictions). These files will have a JSON representation of a -// proto that wraps either the "id" : "" (in case of inline) -// or the document proto (in case of document) but here followed by -// exactly one -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// containing only `code` and `message`. -// -// * For Tables: -// Output depends on whether -// -// [gcs_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.gcs_destination] -// or -// -// [bigquery_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.bigquery_destination] -// is set (either is allowed). -// GCS case: -// In the created directory files `tables_1.csv`, `tables_2.csv`,..., -// `tables_N.csv` will be created, where N may be 1, and depends on -// the total number of the successfully predicted rows. -// For all CLASSIFICATION -// -// [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: -// Each .csv file will contain a header, listing all columns' -// -// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] -// given on input followed by M target column names in the format of -// -// "<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] -// -// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>__score" where M is the number of distinct target values, -// i.e. number of distinct values in the target column of the table -// used to train the model. Subsequent lines will contain the -// respective values of successfully predicted rows, with the last, -// i.e. the target, columns having the corresponding prediction -// [scores][google.cloud.automl.v1beta1.TablesAnnotation.score]. -// For REGRESSION and FORECASTING -// -// [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: -// Each .csv file will contain a header, listing all columns' -// [display_name-s][google.cloud.automl.v1beta1.display_name] given -// on input followed by the predicted target column with name in the -// format of -// -// "predicted_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] -// -// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>" -// Subsequent lines will contain the respective values of -// successfully predicted rows, with the last, i.e. the target, -// column having the predicted target value. -// If prediction for any rows failed, then an additional -// `errors_1.csv`, `errors_2.csv`,..., `errors_N.csv` will be -// created (N depends on total number of failed rows). These files -// will have analogous format as `tables_*.csv`, but always with a -// single target column having -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// represented as a JSON string, and containing only `code` and -// `message`. -// BigQuery case: -// -// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] -// pointing to a BigQuery project must be set. In the given project a -// new dataset will be created with name -// `prediction__` -// where will be made -// BigQuery-dataset-name compatible (e.g. most special characters will -// become underscores), and timestamp will be in -// YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" format. In the dataset -// two tables will be created, `predictions`, and `errors`. -// The `predictions` table's column names will be the input columns' -// -// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] -// followed by the target column with name in the format of -// -// "predicted_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] -// -// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>" -// The input feature columns will contain the respective values of -// successfully predicted rows, with the target column having an -// ARRAY of -// -// [AnnotationPayloads][google.cloud.automl.v1beta1.AnnotationPayload], -// represented as STRUCT-s, containing -// [TablesAnnotation][google.cloud.automl.v1beta1.TablesAnnotation]. -// The `errors` table contains rows for which the prediction has -// failed, it has analogous input columns while the target column name -// is in the format of -// -// "errors_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] -// -// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>", -// and as a value has -// -// [`google.rpc.Status`](https: -// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) -// represented as a STRUCT, and containing only `code` and `message`. -message BatchPredictOutputConfig { - // Required. The destination of the output. - oneof destination { - // The Google Cloud Storage location of the directory where the output is to - // be written to. - GcsDestination gcs_destination = 1; - - // The BigQuery location where the output is to be written to. - BigQueryDestination bigquery_destination = 2; - } -} - -// Output configuration for ModelExport Action. -message ModelExportOutputConfig { - // Required. The destination of the output. - oneof destination { - // The Google Cloud Storage location where the model is to be written to. - // This location may only be set for the following model formats: - // "tflite", "edgetpu_tflite", "tf_saved_model", "tf_js", "core_ml". - // - // Under the directory given as the destination a new one with name - // "model-export--", - // where timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format, - // will be created. Inside the model and any of its supporting files - // will be written. - GcsDestination gcs_destination = 1; - - // The GCR location where model image is to be pushed to. This location - // may only be set for the following model formats: - // "docker". - // - // The model image will be created under the given URI. - GcrDestination gcr_destination = 3; - } - - // The format in which the model must be exported. The available, and default, - // formats depend on the problem and model type (if given problem and type - // combination doesn't have a format listed, it means its models are not - // exportable): - // - // * For Image Classification mobile-low-latency-1, mobile-versatile-1, - // mobile-high-accuracy-1: - // "tflite" (default), "edgetpu_tflite", "tf_saved_model", "tf_js", - // "docker". - // - // * For Image Classification mobile-core-ml-low-latency-1, - // mobile-core-ml-versatile-1, mobile-core-ml-high-accuracy-1: - // "core_ml" (default). - // Formats description: - // - // * tflite - Used for Android mobile devices. - // * edgetpu_tflite - Used for [Edge TPU](https://cloud.google.com/edge-tpu/) - // devices. - // * tf_saved_model - A tensorflow model in SavedModel format. - // * tf_js - A [TensorFlow.js](https://www.tensorflow.org/js) model that can - // be used in the browser and in Node.js using JavaScript. - // * docker - Used for Docker containers. Use the params field to customize - // the container. The container is verified to work correctly on - // ubuntu 16.04 operating system. See more at - // [containers - // - // quickstart](https: - // //cloud.google.com/vision/automl/docs/containers-gcs-quickstart) - // * core_ml - Used for iOS mobile devices. - string model_format = 4; - - // Additional model-type and format specific parameters describing the - // requirements for the to be exported model files, any string must be up to - // 25000 characters long. - // - // * For `docker` format: - // `cpu_architecture` - (string) "x86_64" (default). - // `gpu_architecture` - (string) "none" (default), "nvidia". - map params = 2; -} - -// Output configuration for ExportEvaluatedExamples Action. Note that this call -// is available only for 30 days since the moment the model was evaluated. -// The output depends on the domain, as follows (note that only examples from -// the TEST set are exported): -// -// * For Tables: -// -// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] -// pointing to a BigQuery project must be set. In the given project a -// new dataset will be created with name -// -// `export_evaluated_examples__` -// where will be made BigQuery-dataset-name -// compatible (e.g. most special characters will become underscores), -// and timestamp will be in YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" -// format. In the dataset an `evaluated_examples` table will be -// created. It will have all the same columns as the -// -// [primary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_spec_id] -// of the -// [dataset][google.cloud.automl.v1beta1.Model.dataset_id] from which -// the model was created, as they were at the moment of model's -// evaluation (this includes the target column with its ground -// truth), followed by a column called "predicted_". That -// last column will contain the model's prediction result for each -// respective row, given as ARRAY of -// [AnnotationPayloads][google.cloud.automl.v1beta1.AnnotationPayload], -// represented as STRUCT-s, containing -// [TablesAnnotation][google.cloud.automl.v1beta1.TablesAnnotation]. -message ExportEvaluatedExamplesOutputConfig { - // Required. The destination of the output. - oneof destination { - // The BigQuery location where the output is to be written to. - BigQueryDestination bigquery_destination = 2; - } -} - -// The Google Cloud Storage location for the input content. -message GcsSource { - // Required. Google Cloud Storage URIs to input files, up to 2000 characters - // long. Accepted forms: - // * Full object path, e.g. gs://bucket/directory/object.csv - repeated string input_uris = 1; -} - -// The BigQuery location for the input content. -message BigQuerySource { - // Required. BigQuery URI to a table, up to 2000 characters long. - // Accepted forms: - // * BigQuery path e.g. bq://projectId.bqDatasetId.bqTableId - string input_uri = 1; -} - -// The Google Cloud Storage location where the output is to be written to. -message GcsDestination { - // Required. Google Cloud Storage URI to output directory, up to 2000 - // characters long. - // Accepted forms: - // * Prefix path: gs://bucket/directory - // The requesting user must have write permission to the bucket. - // The directory is created if it doesn't exist. - string output_uri_prefix = 1; -} - -// The BigQuery location for the output content. -message BigQueryDestination { - // Required. BigQuery URI to a project, up to 2000 characters long. - // Accepted forms: - // * BigQuery path e.g. bq://projectId - string output_uri = 1; -} - -// The GCR location where the image must be pushed to. -message GcrDestination { - // Required. Google Contained Registry URI of the new image, up to 2000 - // characters long. See - // - // https: - // //cloud.google.com/container-registry/do - // // cs/pushing-and-pulling#pushing_an_image_to_a_registry - // Accepted forms: - // * [HOSTNAME]/[PROJECT-ID]/[IMAGE] - // * [HOSTNAME]/[PROJECT-ID]/[IMAGE]:[TAG] - // - // The requesting user must have permission to push images the project. - string output_uri = 1; -} diff --git a/google/cloud/automl_v1beta1/proto/model.proto b/google/cloud/automl_v1beta1/proto/model.proto deleted file mode 100644 index 2b2e8d73..00000000 --- a/google/cloud/automl_v1beta1/proto/model.proto +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/image.proto"; -import "google/cloud/automl/v1beta1/tables.proto"; -import "google/cloud/automl/v1beta1/text.proto"; -import "google/cloud/automl/v1beta1/translation.proto"; -import "google/cloud/automl/v1beta1/video.proto"; -import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// API proto representing a trained machine learning model. -message Model { - option (google.api.resource) = { - type: "automl.googleapis.com/Model" - pattern: "projects/{project}/locations/{location}/models/{model}" - }; - - // Deployment state of the model. - enum DeploymentState { - // Should not be used, an un-set enum has this value by default. - DEPLOYMENT_STATE_UNSPECIFIED = 0; - - // Model is deployed. - DEPLOYED = 1; - - // Model is not deployed. - UNDEPLOYED = 2; - } - - // Required. - // The model metadata that is specific to the problem type. - // Must match the metadata type of the dataset used to train the model. - oneof model_metadata { - // Metadata for translation models. - TranslationModelMetadata translation_model_metadata = 15; - - // Metadata for image classification models. - ImageClassificationModelMetadata image_classification_model_metadata = 13; - - // Metadata for text classification models. - TextClassificationModelMetadata text_classification_model_metadata = 14; - - // Metadata for image object detection models. - ImageObjectDetectionModelMetadata image_object_detection_model_metadata = 20; - - // Metadata for video classification models. - VideoClassificationModelMetadata video_classification_model_metadata = 23; - - // Metadata for video object tracking models. - VideoObjectTrackingModelMetadata video_object_tracking_model_metadata = 21; - - // Metadata for text extraction models. - TextExtractionModelMetadata text_extraction_model_metadata = 19; - - // Metadata for Tables models. - TablesModelMetadata tables_model_metadata = 24; - - // Metadata for text sentiment models. - TextSentimentModelMetadata text_sentiment_model_metadata = 22; - } - - // Output only. Resource name of the model. - // Format: `projects/{project_id}/locations/{location_id}/models/{model_id}` - string name = 1; - - // Required. The name of the model to show in the interface. The name can be - // up to 32 characters long and can consist only of ASCII Latin letters A-Z - // and a-z, underscores - // (_), and ASCII digits 0-9. It must start with a letter. - string display_name = 2; - - // Required. The resource ID of the dataset used to create the model. The dataset must - // come from the same ancestor project and location. - string dataset_id = 3; - - // Output only. Timestamp when the model training finished and can be used for prediction. - google.protobuf.Timestamp create_time = 7; - - // Output only. Timestamp when this model was last updated. - google.protobuf.Timestamp update_time = 11; - - // Output only. Deployment state of the model. A model can only serve - // prediction requests after it gets deployed. - DeploymentState deployment_state = 8; -} diff --git a/google/cloud/automl_v1beta1/proto/model_evaluation.proto b/google/cloud/automl_v1beta1/proto/model_evaluation.proto deleted file mode 100644 index d5633fcd..00000000 --- a/google/cloud/automl_v1beta1/proto/model_evaluation.proto +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/cloud/automl/v1beta1/detection.proto"; -import "google/cloud/automl/v1beta1/regression.proto"; -import "google/cloud/automl/v1beta1/tables.proto"; -import "google/cloud/automl/v1beta1/text_extraction.proto"; -import "google/cloud/automl/v1beta1/text_sentiment.proto"; -import "google/cloud/automl/v1beta1/translation.proto"; -import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Evaluation results of a model. -message ModelEvaluation { - option (google.api.resource) = { - type: "automl.googleapis.com/ModelEvaluation" - pattern: "projects/{project}/locations/{location}/models/{model}/modelEvaluations/{model_evaluation}" - }; - - // Output only. Problem type specific evaluation metrics. - oneof metrics { - // Model evaluation metrics for image, text, video and tables - // classification. - // Tables problem is considered a classification when the target column - // is CATEGORY DataType. - ClassificationEvaluationMetrics classification_evaluation_metrics = 8; - - // Model evaluation metrics for Tables regression. - // Tables problem is considered a regression when the target column - // has FLOAT64 DataType. - RegressionEvaluationMetrics regression_evaluation_metrics = 24; - - // Model evaluation metrics for translation. - TranslationEvaluationMetrics translation_evaluation_metrics = 9; - - // Model evaluation metrics for image object detection. - ImageObjectDetectionEvaluationMetrics image_object_detection_evaluation_metrics = 12; - - // Model evaluation metrics for video object tracking. - VideoObjectTrackingEvaluationMetrics video_object_tracking_evaluation_metrics = 14; - - // Evaluation metrics for text sentiment models. - TextSentimentEvaluationMetrics text_sentiment_evaluation_metrics = 11; - - // Evaluation metrics for text extraction models. - TextExtractionEvaluationMetrics text_extraction_evaluation_metrics = 13; - } - - // Output only. Resource name of the model evaluation. - // Format: - // - // `projects/{project_id}/locations/{location_id}/models/{model_id}/modelEvaluations/{model_evaluation_id}` - string name = 1; - - // Output only. The ID of the annotation spec that the model evaluation applies to. The - // The ID is empty for the overall model evaluation. - // For Tables annotation specs in the dataset do not exist and this ID is - // always not set, but for CLASSIFICATION - // - // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] - // the - // [display_name][google.cloud.automl.v1beta1.ModelEvaluation.display_name] - // field is used. - string annotation_spec_id = 2; - - // Output only. The value of - // [display_name][google.cloud.automl.v1beta1.AnnotationSpec.display_name] at - // the moment when the model was trained. Because this field returns a value - // at model training time, for different models trained from the same dataset, - // the values may differ, since display names could had been changed between - // the two model's trainings. - // For Tables CLASSIFICATION - // - // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] - // distinct values of the target column at the moment of the model evaluation - // are populated here. - // The display_name is empty for the overall model evaluation. - string display_name = 15; - - // Output only. Timestamp when this model evaluation was created. - google.protobuf.Timestamp create_time = 5; - - // Output only. The number of examples used for model evaluation, i.e. for - // which ground truth from time of model creation is compared against the - // predicted annotations created by the model. - // For overall ModelEvaluation (i.e. with annotation_spec_id not set) this is - // the total number of all examples used for evaluation. - // Otherwise, this is the count of examples that according to the ground - // truth were annotated by the - // - // [annotation_spec_id][google.cloud.automl.v1beta1.ModelEvaluation.annotation_spec_id]. - int32 evaluated_example_count = 6; -} diff --git a/google/cloud/automl_v1beta1/proto/operations.proto b/google/cloud/automl_v1beta1/proto/operations.proto deleted file mode 100644 index cce3fedc..00000000 --- a/google/cloud/automl_v1beta1/proto/operations.proto +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/io.proto"; -import "google/cloud/automl/v1beta1/model.proto"; -import "google/cloud/automl/v1beta1/model_evaluation.proto"; -import "google/protobuf/empty.proto"; -import "google/protobuf/timestamp.proto"; -import "google/rpc/status.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Metadata used across all long running operations returned by AutoML API. -message OperationMetadata { - // Ouptut only. Details of specific operation. Even if this field is empty, - // the presence allows to distinguish different types of operations. - oneof details { - // Details of a Delete operation. - DeleteOperationMetadata delete_details = 8; - - // Details of a DeployModel operation. - DeployModelOperationMetadata deploy_model_details = 24; - - // Details of an UndeployModel operation. - UndeployModelOperationMetadata undeploy_model_details = 25; - - // Details of CreateModel operation. - CreateModelOperationMetadata create_model_details = 10; - - // Details of ImportData operation. - ImportDataOperationMetadata import_data_details = 15; - - // Details of BatchPredict operation. - BatchPredictOperationMetadata batch_predict_details = 16; - - // Details of ExportData operation. - ExportDataOperationMetadata export_data_details = 21; - - // Details of ExportModel operation. - ExportModelOperationMetadata export_model_details = 22; - - // Details of ExportEvaluatedExamples operation. - ExportEvaluatedExamplesOperationMetadata export_evaluated_examples_details = 26; - } - - // Output only. Progress of operation. Range: [0, 100]. - // Not used currently. - int32 progress_percent = 13; - - // Output only. Partial failures encountered. - // E.g. single files that couldn't be read. - // This field should never exceed 20 entries. - // Status details field will contain standard GCP error details. - repeated google.rpc.Status partial_failures = 2; - - // Output only. Time when the operation was created. - google.protobuf.Timestamp create_time = 3; - - // Output only. Time when the operation was updated for the last time. - google.protobuf.Timestamp update_time = 4; -} - -// Details of operations that perform deletes of any entities. -message DeleteOperationMetadata { - -} - -// Details of DeployModel operation. -message DeployModelOperationMetadata { - -} - -// Details of UndeployModel operation. -message UndeployModelOperationMetadata { - -} - -// Details of CreateModel operation. -message CreateModelOperationMetadata { - -} - -// Details of ImportData operation. -message ImportDataOperationMetadata { - -} - -// Details of ExportData operation. -message ExportDataOperationMetadata { - // Further describes this export data's output. - // Supplements - // [OutputConfig][google.cloud.automl.v1beta1.OutputConfig]. - message ExportDataOutputInfo { - // The output location to which the exported data is written. - oneof output_location { - // The full path of the Google Cloud Storage directory created, into which - // the exported data is written. - string gcs_output_directory = 1; - - // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId - // format, into which the exported data is written. - string bigquery_output_dataset = 2; - } - } - - // Output only. Information further describing this export data's output. - ExportDataOutputInfo output_info = 1; -} - -// Details of BatchPredict operation. -message BatchPredictOperationMetadata { - // Further describes this batch predict's output. - // Supplements - // - // [BatchPredictOutputConfig][google.cloud.automl.v1beta1.BatchPredictOutputConfig]. - message BatchPredictOutputInfo { - // The output location into which prediction output is written. - oneof output_location { - // The full path of the Google Cloud Storage directory created, into which - // the prediction output is written. - string gcs_output_directory = 1; - - // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId - // format, into which the prediction output is written. - string bigquery_output_dataset = 2; - } - } - - // Output only. The input config that was given upon starting this - // batch predict operation. - BatchPredictInputConfig input_config = 1; - - // Output only. Information further describing this batch predict's output. - BatchPredictOutputInfo output_info = 2; -} - -// Details of ExportModel operation. -message ExportModelOperationMetadata { - // Further describes the output of model export. - // Supplements - // - // [ModelExportOutputConfig][google.cloud.automl.v1beta1.ModelExportOutputConfig]. - message ExportModelOutputInfo { - // The full path of the Google Cloud Storage directory created, into which - // the model will be exported. - string gcs_output_directory = 1; - } - - // Output only. Information further describing the output of this model - // export. - ExportModelOutputInfo output_info = 2; -} - -// Details of EvaluatedExamples operation. -message ExportEvaluatedExamplesOperationMetadata { - // Further describes the output of the evaluated examples export. - // Supplements - // - // [ExportEvaluatedExamplesOutputConfig][google.cloud.automl.v1beta1.ExportEvaluatedExamplesOutputConfig]. - message ExportEvaluatedExamplesOutputInfo { - // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId - // format, into which the output of export evaluated examples is written. - string bigquery_output_dataset = 2; - } - - // Output only. Information further describing the output of this evaluated - // examples export. - ExportEvaluatedExamplesOutputInfo output_info = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/prediction_service.proto b/google/cloud/automl_v1beta1/proto/prediction_service.proto deleted file mode 100644 index 0bcf685e..00000000 --- a/google/cloud/automl_v1beta1/proto/prediction_service.proto +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/annotation_payload.proto"; -import "google/cloud/automl/v1beta1/data_items.proto"; -import "google/cloud/automl/v1beta1/io.proto"; -import "google/cloud/automl/v1beta1/operations.proto"; -import "google/longrunning/operations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "PredictionServiceProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// AutoML Prediction API. -// -// On any input that is documented to expect a string parameter in -// snake_case or kebab-case, either of those cases is accepted. -service PredictionService { - option (google.api.default_host) = "automl.googleapis.com"; - option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; - - // Perform an online prediction. The prediction result will be directly - // returned in the response. - // Available for following ML problems, and their expected request payloads: - // * Image Classification - Image in .JPEG, .GIF or .PNG format, image_bytes - // up to 30MB. - // * Image Object Detection - Image in .JPEG, .GIF or .PNG format, image_bytes - // up to 30MB. - // * Text Classification - TextSnippet, content up to 60,000 characters, - // UTF-8 encoded. - // * Text Extraction - TextSnippet, content up to 30,000 characters, - // UTF-8 NFC encoded. - // * Translation - TextSnippet, content up to 25,000 characters, UTF-8 - // encoded. - // * Tables - Row, with column values matching the columns of the model, - // up to 5MB. Not available for FORECASTING - // - // [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]. - // * Text Sentiment - TextSnippet, content up 500 characters, UTF-8 - // encoded. - rpc Predict(PredictRequest) returns (PredictResponse) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/models/*}:predict" - body: "*" - }; - option (google.api.method_signature) = "name,payload,params"; - } - - // Perform a batch prediction. Unlike the online [Predict][google.cloud.automl.v1beta1.PredictionService.Predict], batch - // prediction result won't be immediately available in the response. Instead, - // a long running operation object is returned. User can poll the operation - // result via [GetOperation][google.longrunning.Operations.GetOperation] - // method. Once the operation is done, [BatchPredictResult][google.cloud.automl.v1beta1.BatchPredictResult] is returned in - // the [response][google.longrunning.Operation.response] field. - // Available for following ML problems: - // * Image Classification - // * Image Object Detection - // * Video Classification - // * Video Object Tracking * Text Extraction - // * Tables - rpc BatchPredict(BatchPredictRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/models/*}:batchPredict" - body: "*" - }; - option (google.api.method_signature) = "name,input_config,output_config,params"; - option (google.longrunning.operation_info) = { - response_type: "BatchPredictResult" - metadata_type: "OperationMetadata" - }; - } -} - -// Request message for [PredictionService.Predict][google.cloud.automl.v1beta1.PredictionService.Predict]. -message PredictRequest { - // Required. Name of the model requested to serve the prediction. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; - - // Required. Payload to perform a prediction on. The payload must match the - // problem type that the model was trained to solve. - ExamplePayload payload = 2 [(google.api.field_behavior) = REQUIRED]; - - // Additional domain-specific parameters, any string must be up to 25000 - // characters long. - // - // * For Image Classification: - // - // `score_threshold` - (float) A value from 0.0 to 1.0. When the model - // makes predictions for an image, it will only produce results that have - // at least this confidence score. The default is 0.5. - // - // * For Image Object Detection: - // `score_threshold` - (float) When Model detects objects on the image, - // it will only produce bounding boxes which have at least this - // confidence score. Value in 0 to 1 range, default is 0.5. - // `max_bounding_box_count` - (int64) No more than this number of bounding - // boxes will be returned in the response. Default is 100, the - // requested value may be limited by server. - // * For Tables: - // feature_importance - (boolean) Whether feature importance - // should be populated in the returned TablesAnnotation. - // The default is false. - map params = 3; -} - -// Response message for [PredictionService.Predict][google.cloud.automl.v1beta1.PredictionService.Predict]. -message PredictResponse { - // Prediction result. - // Translation and Text Sentiment will return precisely one payload. - repeated AnnotationPayload payload = 1; - - // The preprocessed example that AutoML actually makes prediction on. - // Empty if AutoML does not preprocess the input example. - // * For Text Extraction: - // If the input is a .pdf file, the OCR'ed text will be provided in - // [document_text][google.cloud.automl.v1beta1.Document.document_text]. - ExamplePayload preprocessed_input = 3; - - // Additional domain-specific prediction response metadata. - // - // * For Image Object Detection: - // `max_bounding_box_count` - (int64) At most that many bounding boxes per - // image could have been returned. - // - // * For Text Sentiment: - // `sentiment_score` - (float, deprecated) A value between -1 and 1, - // -1 maps to least positive sentiment, while 1 maps to the most positive - // one and the higher the score, the more positive the sentiment in the - // document is. Yet these values are relative to the training data, so - // e.g. if all data was positive then -1 will be also positive (though - // the least). - // The sentiment_score shouldn't be confused with "score" or "magnitude" - // from the previous Natural Language Sentiment Analysis API. - map metadata = 2; -} - -// Request message for [PredictionService.BatchPredict][google.cloud.automl.v1beta1.PredictionService.BatchPredict]. -message BatchPredictRequest { - // Required. Name of the model requested to serve the batch prediction. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; - - // Required. The input configuration for batch prediction. - BatchPredictInputConfig input_config = 3 [(google.api.field_behavior) = REQUIRED]; - - // Required. The Configuration specifying where output predictions should - // be written. - BatchPredictOutputConfig output_config = 4 [(google.api.field_behavior) = REQUIRED]; - - // Required. Additional domain-specific parameters for the predictions, any string must - // be up to 25000 characters long. - // - // * For Text Classification: - // - // `score_threshold` - (float) A value from 0.0 to 1.0. When the model - // makes predictions for a text snippet, it will only produce results - // that have at least this confidence score. The default is 0.5. - // - // * For Image Classification: - // - // `score_threshold` - (float) A value from 0.0 to 1.0. When the model - // makes predictions for an image, it will only produce results that - // have at least this confidence score. The default is 0.5. - // - // * For Image Object Detection: - // - // `score_threshold` - (float) When Model detects objects on the image, - // it will only produce bounding boxes which have at least this - // confidence score. Value in 0 to 1 range, default is 0.5. - // `max_bounding_box_count` - (int64) No more than this number of bounding - // boxes will be produced per image. Default is 100, the - // requested value may be limited by server. - // - // * For Video Classification : - // - // `score_threshold` - (float) A value from 0.0 to 1.0. When the model - // makes predictions for a video, it will only produce results that - // have at least this confidence score. The default is 0.5. - // `segment_classification` - (boolean) Set to true to request - // segment-level classification. AutoML Video Intelligence returns - // labels and their confidence scores for the entire segment of the - // video that user specified in the request configuration. - // The default is "true". - // `shot_classification` - (boolean) Set to true to request shot-level - // classification. AutoML Video Intelligence determines the boundaries - // for each camera shot in the entire segment of the video that user - // specified in the request configuration. AutoML Video Intelligence - // then returns labels and their confidence scores for each detected - // shot, along with the start and end time of the shot. - // WARNING: Model evaluation is not done for this classification type, - // the quality of it depends on training data, but there are no metrics - // provided to describe that quality. The default is "false". - // `1s_interval_classification` - (boolean) Set to true to request - // classification for a video at one-second intervals. AutoML Video - // Intelligence returns labels and their confidence scores for each - // second of the entire segment of the video that user specified in the - // request configuration. - // WARNING: Model evaluation is not done for this classification - // type, the quality of it depends on training data, but there are no - // metrics provided to describe that quality. The default is - // "false". - // - // * For Tables: - // - // feature_importance - (boolean) Whether feature importance - // should be populated in the returned TablesAnnotations. The - // default is false. - // - // * For Video Object Tracking: - // - // `score_threshold` - (float) When Model detects objects on video frames, - // it will only produce bounding boxes which have at least this - // confidence score. Value in 0 to 1 range, default is 0.5. - // `max_bounding_box_count` - (int64) No more than this number of bounding - // boxes will be returned per frame. Default is 100, the requested - // value may be limited by server. - // `min_bounding_box_size` - (float) Only bounding boxes with shortest edge - // at least that long as a relative value of video frame size will be - // returned. Value in 0 to 1 range. Default is 0. - map params = 5 [(google.api.field_behavior) = REQUIRED]; -} - -// Result of the Batch Predict. This message is returned in -// [response][google.longrunning.Operation.response] of the operation returned -// by the [PredictionService.BatchPredict][google.cloud.automl.v1beta1.PredictionService.BatchPredict]. -message BatchPredictResult { - // Additional domain-specific prediction response metadata. - // - // * For Image Object Detection: - // `max_bounding_box_count` - (int64) At most that many bounding boxes per - // image could have been returned. - // - // * For Video Object Tracking: - // `max_bounding_box_count` - (int64) At most that many bounding boxes per - // frame could have been returned. - map metadata = 1; -} diff --git a/google/cloud/automl_v1beta1/proto/ranges.proto b/google/cloud/automl_v1beta1/proto/ranges.proto deleted file mode 100644 index 89572bb0..00000000 --- a/google/cloud/automl_v1beta1/proto/ranges.proto +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "RangesProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A range between two double numbers. -message DoubleRange { - // Start of the range, inclusive. - double start = 1; - - // End of the range, exclusive. - double end = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/regression.proto b/google/cloud/automl_v1beta1/proto/regression.proto deleted file mode 100644 index 1286d3d8..00000000 --- a/google/cloud/automl_v1beta1/proto/regression.proto +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_outer_classname = "RegressionProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Metrics for regression problems. -message RegressionEvaluationMetrics { - // Output only. Root Mean Squared Error (RMSE). - float root_mean_squared_error = 1; - - // Output only. Mean Absolute Error (MAE). - float mean_absolute_error = 2; - - // Output only. Mean absolute percentage error. Only set if all ground truth - // values are are positive. - float mean_absolute_percentage_error = 3; - - // Output only. R squared. - float r_squared = 4; - - // Output only. Root mean squared log error. - float root_mean_squared_log_error = 5; -} diff --git a/google/cloud/automl_v1beta1/proto/service.proto b/google/cloud/automl_v1beta1/proto/service.proto deleted file mode 100644 index a421ece1..00000000 --- a/google/cloud/automl_v1beta1/proto/service.proto +++ /dev/null @@ -1,800 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/annotation_payload.proto"; -import "google/cloud/automl/v1beta1/annotation_spec.proto"; -import "google/cloud/automl/v1beta1/column_spec.proto"; -import "google/cloud/automl/v1beta1/dataset.proto"; -import "google/cloud/automl/v1beta1/image.proto"; -import "google/cloud/automl/v1beta1/io.proto"; -import "google/cloud/automl/v1beta1/model.proto"; -import "google/cloud/automl/v1beta1/model_evaluation.proto"; -import "google/cloud/automl/v1beta1/operations.proto"; -import "google/cloud/automl/v1beta1/table_spec.proto"; -import "google/longrunning/operations.proto"; -import "google/protobuf/field_mask.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "AutoMlProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// AutoML Server API. -// -// The resource names are assigned by the server. -// The server never reuses names that it has created after the resources with -// those names are deleted. -// -// An ID of a resource is the last element of the item's resource name. For -// `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}`, then -// the id for the item is `{dataset_id}`. -// -// Currently the only supported `location_id` is "us-central1". -// -// On any input that is documented to expect a string parameter in -// snake_case or kebab-case, either of those cases is accepted. -service AutoMl { - option (google.api.default_host) = "automl.googleapis.com"; - option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; - - // Creates a dataset. - rpc CreateDataset(CreateDatasetRequest) returns (Dataset) { - option (google.api.http) = { - post: "/v1beta1/{parent=projects/*/locations/*}/datasets" - body: "dataset" - }; - option (google.api.method_signature) = "parent,dataset"; - } - - // Gets a dataset. - rpc GetDataset(GetDatasetRequest) returns (Dataset) { - option (google.api.http) = { - get: "/v1beta1/{name=projects/*/locations/*/datasets/*}" - }; - option (google.api.method_signature) = "name"; - } - - // Lists datasets in a project. - rpc ListDatasets(ListDatasetsRequest) returns (ListDatasetsResponse) { - option (google.api.http) = { - get: "/v1beta1/{parent=projects/*/locations/*}/datasets" - }; - option (google.api.method_signature) = "parent"; - } - - // Updates a dataset. - rpc UpdateDataset(UpdateDatasetRequest) returns (Dataset) { - option (google.api.http) = { - patch: "/v1beta1/{dataset.name=projects/*/locations/*/datasets/*}" - body: "dataset" - }; - option (google.api.method_signature) = "dataset"; - } - - // Deletes a dataset and all of its contents. - // Returns empty response in the - // [response][google.longrunning.Operation.response] field when it completes, - // and `delete_details` in the - // [metadata][google.longrunning.Operation.metadata] field. - rpc DeleteDataset(DeleteDatasetRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - delete: "/v1beta1/{name=projects/*/locations/*/datasets/*}" - }; - option (google.api.method_signature) = "name"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Imports data into a dataset. - // For Tables this method can only be called on an empty Dataset. - // - // For Tables: - // * A - // [schema_inference_version][google.cloud.automl.v1beta1.InputConfig.params] - // parameter must be explicitly set. - // Returns an empty response in the - // [response][google.longrunning.Operation.response] field when it completes. - rpc ImportData(ImportDataRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/datasets/*}:importData" - body: "*" - }; - option (google.api.method_signature) = "name,input_config"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Exports dataset's data to the provided output location. - // Returns an empty response in the - // [response][google.longrunning.Operation.response] field when it completes. - rpc ExportData(ExportDataRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/datasets/*}:exportData" - body: "*" - }; - option (google.api.method_signature) = "name,output_config"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Gets an annotation spec. - rpc GetAnnotationSpec(GetAnnotationSpecRequest) returns (AnnotationSpec) { - option (google.api.http) = { - get: "/v1beta1/{name=projects/*/locations/*/datasets/*/annotationSpecs/*}" - }; - option (google.api.method_signature) = "name"; - } - - // Gets a table spec. - rpc GetTableSpec(GetTableSpecRequest) returns (TableSpec) { - option (google.api.http) = { - get: "/v1beta1/{name=projects/*/locations/*/datasets/*/tableSpecs/*}" - }; - option (google.api.method_signature) = "name"; - } - - // Lists table specs in a dataset. - rpc ListTableSpecs(ListTableSpecsRequest) returns (ListTableSpecsResponse) { - option (google.api.http) = { - get: "/v1beta1/{parent=projects/*/locations/*/datasets/*}/tableSpecs" - }; - option (google.api.method_signature) = "parent"; - } - - // Updates a table spec. - rpc UpdateTableSpec(UpdateTableSpecRequest) returns (TableSpec) { - option (google.api.http) = { - patch: "/v1beta1/{table_spec.name=projects/*/locations/*/datasets/*/tableSpecs/*}" - body: "table_spec" - }; - option (google.api.method_signature) = "table_spec"; - } - - // Gets a column spec. - rpc GetColumnSpec(GetColumnSpecRequest) returns (ColumnSpec) { - option (google.api.http) = { - get: "/v1beta1/{name=projects/*/locations/*/datasets/*/tableSpecs/*/columnSpecs/*}" - }; - option (google.api.method_signature) = "name"; - } - - // Lists column specs in a table spec. - rpc ListColumnSpecs(ListColumnSpecsRequest) returns (ListColumnSpecsResponse) { - option (google.api.http) = { - get: "/v1beta1/{parent=projects/*/locations/*/datasets/*/tableSpecs/*}/columnSpecs" - }; - option (google.api.method_signature) = "parent"; - } - - // Updates a column spec. - rpc UpdateColumnSpec(UpdateColumnSpecRequest) returns (ColumnSpec) { - option (google.api.http) = { - patch: "/v1beta1/{column_spec.name=projects/*/locations/*/datasets/*/tableSpecs/*/columnSpecs/*}" - body: "column_spec" - }; - option (google.api.method_signature) = "column_spec"; - } - - // Creates a model. - // Returns a Model in the [response][google.longrunning.Operation.response] - // field when it completes. - // When you create a model, several model evaluations are created for it: - // a global evaluation, and one evaluation for each annotation spec. - rpc CreateModel(CreateModelRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{parent=projects/*/locations/*}/models" - body: "model" - }; - option (google.api.method_signature) = "parent,model"; - option (google.longrunning.operation_info) = { - response_type: "Model" - metadata_type: "OperationMetadata" - }; - } - - // Gets a model. - rpc GetModel(GetModelRequest) returns (Model) { - option (google.api.http) = { - get: "/v1beta1/{name=projects/*/locations/*/models/*}" - }; - option (google.api.method_signature) = "name"; - } - - // Lists models. - rpc ListModels(ListModelsRequest) returns (ListModelsResponse) { - option (google.api.http) = { - get: "/v1beta1/{parent=projects/*/locations/*}/models" - }; - option (google.api.method_signature) = "parent"; - } - - // Deletes a model. - // Returns `google.protobuf.Empty` in the - // [response][google.longrunning.Operation.response] field when it completes, - // and `delete_details` in the - // [metadata][google.longrunning.Operation.metadata] field. - rpc DeleteModel(DeleteModelRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - delete: "/v1beta1/{name=projects/*/locations/*/models/*}" - }; - option (google.api.method_signature) = "name"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Deploys a model. If a model is already deployed, deploying it with the - // same parameters has no effect. Deploying with different parametrs - // (as e.g. changing - // - // [node_number][google.cloud.automl.v1beta1.ImageObjectDetectionModelDeploymentMetadata.node_number]) - // will reset the deployment state without pausing the model's availability. - // - // Only applicable for Text Classification, Image Object Detection , Tables, and Image Segmentation; all other domains manage - // deployment automatically. - // - // Returns an empty response in the - // [response][google.longrunning.Operation.response] field when it completes. - rpc DeployModel(DeployModelRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/models/*}:deploy" - body: "*" - }; - option (google.api.method_signature) = "name"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Undeploys a model. If the model is not deployed this method has no effect. - // - // Only applicable for Text Classification, Image Object Detection and Tables; - // all other domains manage deployment automatically. - // - // Returns an empty response in the - // [response][google.longrunning.Operation.response] field when it completes. - rpc UndeployModel(UndeployModelRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/models/*}:undeploy" - body: "*" - }; - option (google.api.method_signature) = "name"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Exports a trained, "export-able", model to a user specified Google Cloud - // Storage location. A model is considered export-able if and only if it has - // an export format defined for it in - // - // [ModelExportOutputConfig][google.cloud.automl.v1beta1.ModelExportOutputConfig]. - // - // Returns an empty response in the - // [response][google.longrunning.Operation.response] field when it completes. - rpc ExportModel(ExportModelRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/models/*}:export" - body: "*" - }; - option (google.api.method_signature) = "name,output_config"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Exports examples on which the model was evaluated (i.e. which were in the - // TEST set of the dataset the model was created from), together with their - // ground truth annotations and the annotations created (predicted) by the - // model. - // The examples, ground truth and predictions are exported in the state - // they were at the moment the model was evaluated. - // - // This export is available only for 30 days since the model evaluation is - // created. - // - // Currently only available for Tables. - // - // Returns an empty response in the - // [response][google.longrunning.Operation.response] field when it completes. - rpc ExportEvaluatedExamples(ExportEvaluatedExamplesRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - post: "/v1beta1/{name=projects/*/locations/*/models/*}:exportEvaluatedExamples" - body: "*" - }; - option (google.api.method_signature) = "name,output_config"; - option (google.longrunning.operation_info) = { - response_type: "google.protobuf.Empty" - metadata_type: "OperationMetadata" - }; - } - - // Gets a model evaluation. - rpc GetModelEvaluation(GetModelEvaluationRequest) returns (ModelEvaluation) { - option (google.api.http) = { - get: "/v1beta1/{name=projects/*/locations/*/models/*/modelEvaluations/*}" - }; - option (google.api.method_signature) = "name"; - } - - // Lists model evaluations. - rpc ListModelEvaluations(ListModelEvaluationsRequest) returns (ListModelEvaluationsResponse) { - option (google.api.http) = { - get: "/v1beta1/{parent=projects/*/locations/*/models/*}/modelEvaluations" - }; - option (google.api.method_signature) = "parent"; - } -} - -// Request message for [AutoMl.CreateDataset][google.cloud.automl.v1beta1.AutoMl.CreateDataset]. -message CreateDatasetRequest { - // Required. The resource name of the project to create the dataset for. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "locations.googleapis.com/Location" - } - ]; - - // Required. The dataset to create. - Dataset dataset = 2 [(google.api.field_behavior) = REQUIRED]; -} - -// Request message for [AutoMl.GetDataset][google.cloud.automl.v1beta1.AutoMl.GetDataset]. -message GetDatasetRequest { - // Required. The resource name of the dataset to retrieve. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Dataset" - } - ]; -} - -// Request message for [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets]. -message ListDatasetsRequest { - // Required. The resource name of the project from which to list datasets. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "locations.googleapis.com/Location" - } - ]; - - // An expression for filtering the results of the request. - // - // * `dataset_metadata` - for existence of the case (e.g. - // image_classification_dataset_metadata:*). Some examples of using the filter are: - // - // * `translation_dataset_metadata:*` --> The dataset has - // translation_dataset_metadata. - string filter = 3; - - // Requested page size. Server may return fewer results than requested. - // If unspecified, server will pick a default size. - int32 page_size = 4; - - // A token identifying a page of results for the server to return - // Typically obtained via - // [ListDatasetsResponse.next_page_token][google.cloud.automl.v1beta1.ListDatasetsResponse.next_page_token] of the previous - // [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets] call. - string page_token = 6; -} - -// Response message for [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets]. -message ListDatasetsResponse { - // The datasets read. - repeated Dataset datasets = 1; - - // A token to retrieve next page of results. - // Pass to [ListDatasetsRequest.page_token][google.cloud.automl.v1beta1.ListDatasetsRequest.page_token] to obtain that page. - string next_page_token = 2; -} - -// Request message for [AutoMl.UpdateDataset][google.cloud.automl.v1beta1.AutoMl.UpdateDataset] -message UpdateDatasetRequest { - // Required. The dataset which replaces the resource on the server. - Dataset dataset = 1 [(google.api.field_behavior) = REQUIRED]; - - // The update mask applies to the resource. - google.protobuf.FieldMask update_mask = 2; -} - -// Request message for [AutoMl.DeleteDataset][google.cloud.automl.v1beta1.AutoMl.DeleteDataset]. -message DeleteDatasetRequest { - // Required. The resource name of the dataset to delete. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Dataset" - } - ]; -} - -// Request message for [AutoMl.ImportData][google.cloud.automl.v1beta1.AutoMl.ImportData]. -message ImportDataRequest { - // Required. Dataset name. Dataset must already exist. All imported - // annotations and examples will be added. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Dataset" - } - ]; - - // Required. The desired input location and its domain specific semantics, - // if any. - InputConfig input_config = 3 [(google.api.field_behavior) = REQUIRED]; -} - -// Request message for [AutoMl.ExportData][google.cloud.automl.v1beta1.AutoMl.ExportData]. -message ExportDataRequest { - // Required. The resource name of the dataset. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Dataset" - } - ]; - - // Required. The desired output location. - OutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; -} - -// Request message for [AutoMl.GetAnnotationSpec][google.cloud.automl.v1beta1.AutoMl.GetAnnotationSpec]. -message GetAnnotationSpecRequest { - // Required. The resource name of the annotation spec to retrieve. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/AnnotationSpec" - } - ]; -} - -// Request message for [AutoMl.GetTableSpec][google.cloud.automl.v1beta1.AutoMl.GetTableSpec]. -message GetTableSpecRequest { - // Required. The resource name of the table spec to retrieve. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/TableSpec" - } - ]; - - // Mask specifying which fields to read. - google.protobuf.FieldMask field_mask = 2; -} - -// Request message for [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs]. -message ListTableSpecsRequest { - // Required. The resource name of the dataset to list table specs from. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Dataset" - } - ]; - - // Mask specifying which fields to read. - google.protobuf.FieldMask field_mask = 2; - - // Filter expression, see go/filtering. - string filter = 3; - - // Requested page size. The server can return fewer results than requested. - // If unspecified, the server will pick a default size. - int32 page_size = 4; - - // A token identifying a page of results for the server to return. - // Typically obtained from the - // [ListTableSpecsResponse.next_page_token][google.cloud.automl.v1beta1.ListTableSpecsResponse.next_page_token] field of the previous - // [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs] call. - string page_token = 6; -} - -// Response message for [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs]. -message ListTableSpecsResponse { - // The table specs read. - repeated TableSpec table_specs = 1; - - // A token to retrieve next page of results. - // Pass to [ListTableSpecsRequest.page_token][google.cloud.automl.v1beta1.ListTableSpecsRequest.page_token] to obtain that page. - string next_page_token = 2; -} - -// Request message for [AutoMl.UpdateTableSpec][google.cloud.automl.v1beta1.AutoMl.UpdateTableSpec] -message UpdateTableSpecRequest { - // Required. The table spec which replaces the resource on the server. - TableSpec table_spec = 1 [(google.api.field_behavior) = REQUIRED]; - - // The update mask applies to the resource. - google.protobuf.FieldMask update_mask = 2; -} - -// Request message for [AutoMl.GetColumnSpec][google.cloud.automl.v1beta1.AutoMl.GetColumnSpec]. -message GetColumnSpecRequest { - // Required. The resource name of the column spec to retrieve. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/ColumnSpec" - } - ]; - - // Mask specifying which fields to read. - google.protobuf.FieldMask field_mask = 2; -} - -// Request message for [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs]. -message ListColumnSpecsRequest { - // Required. The resource name of the table spec to list column specs from. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/TableSpec" - } - ]; - - // Mask specifying which fields to read. - google.protobuf.FieldMask field_mask = 2; - - // Filter expression, see go/filtering. - string filter = 3; - - // Requested page size. The server can return fewer results than requested. - // If unspecified, the server will pick a default size. - int32 page_size = 4; - - // A token identifying a page of results for the server to return. - // Typically obtained from the - // [ListColumnSpecsResponse.next_page_token][google.cloud.automl.v1beta1.ListColumnSpecsResponse.next_page_token] field of the previous - // [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs] call. - string page_token = 6; -} - -// Response message for [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs]. -message ListColumnSpecsResponse { - // The column specs read. - repeated ColumnSpec column_specs = 1; - - // A token to retrieve next page of results. - // Pass to [ListColumnSpecsRequest.page_token][google.cloud.automl.v1beta1.ListColumnSpecsRequest.page_token] to obtain that page. - string next_page_token = 2; -} - -// Request message for [AutoMl.UpdateColumnSpec][google.cloud.automl.v1beta1.AutoMl.UpdateColumnSpec] -message UpdateColumnSpecRequest { - // Required. The column spec which replaces the resource on the server. - ColumnSpec column_spec = 1 [(google.api.field_behavior) = REQUIRED]; - - // The update mask applies to the resource. - google.protobuf.FieldMask update_mask = 2; -} - -// Request message for [AutoMl.CreateModel][google.cloud.automl.v1beta1.AutoMl.CreateModel]. -message CreateModelRequest { - // Required. Resource name of the parent project where the model is being created. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "locations.googleapis.com/Location" - } - ]; - - // Required. The model to create. - Model model = 4 [(google.api.field_behavior) = REQUIRED]; -} - -// Request message for [AutoMl.GetModel][google.cloud.automl.v1beta1.AutoMl.GetModel]. -message GetModelRequest { - // Required. Resource name of the model. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; -} - -// Request message for [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels]. -message ListModelsRequest { - // Required. Resource name of the project, from which to list the models. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "locations.googleapis.com/Location" - } - ]; - - // An expression for filtering the results of the request. - // - // * `model_metadata` - for existence of the case (e.g. - // video_classification_model_metadata:*). - // * `dataset_id` - for = or !=. Some examples of using the filter are: - // - // * `image_classification_model_metadata:*` --> The model has - // image_classification_model_metadata. - // * `dataset_id=5` --> The model was created from a dataset with ID 5. - string filter = 3; - - // Requested page size. - int32 page_size = 4; - - // A token identifying a page of results for the server to return - // Typically obtained via - // [ListModelsResponse.next_page_token][google.cloud.automl.v1beta1.ListModelsResponse.next_page_token] of the previous - // [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels] call. - string page_token = 6; -} - -// Response message for [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels]. -message ListModelsResponse { - // List of models in the requested page. - repeated Model model = 1; - - // A token to retrieve next page of results. - // Pass to [ListModelsRequest.page_token][google.cloud.automl.v1beta1.ListModelsRequest.page_token] to obtain that page. - string next_page_token = 2; -} - -// Request message for [AutoMl.DeleteModel][google.cloud.automl.v1beta1.AutoMl.DeleteModel]. -message DeleteModelRequest { - // Required. Resource name of the model being deleted. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; -} - -// Request message for [AutoMl.DeployModel][google.cloud.automl.v1beta1.AutoMl.DeployModel]. -message DeployModelRequest { - // The per-domain specific deployment parameters. - oneof model_deployment_metadata { - // Model deployment metadata specific to Image Object Detection. - ImageObjectDetectionModelDeploymentMetadata image_object_detection_model_deployment_metadata = 2; - - // Model deployment metadata specific to Image Classification. - ImageClassificationModelDeploymentMetadata image_classification_model_deployment_metadata = 4; - } - - // Required. Resource name of the model to deploy. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; -} - -// Request message for [AutoMl.UndeployModel][google.cloud.automl.v1beta1.AutoMl.UndeployModel]. -message UndeployModelRequest { - // Required. Resource name of the model to undeploy. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; -} - -// Request message for [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]. -// Models need to be enabled for exporting, otherwise an error code will be -// returned. -message ExportModelRequest { - // Required. The resource name of the model to export. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; - - // Required. The desired output location and configuration. - ModelExportOutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; -} - -// Request message for [AutoMl.ExportEvaluatedExamples][google.cloud.automl.v1beta1.AutoMl.ExportEvaluatedExamples]. -message ExportEvaluatedExamplesRequest { - // Required. The resource name of the model whose evaluated examples are to - // be exported. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; - - // Required. The desired output location and configuration. - ExportEvaluatedExamplesOutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; -} - -// Request message for [AutoMl.GetModelEvaluation][google.cloud.automl.v1beta1.AutoMl.GetModelEvaluation]. -message GetModelEvaluationRequest { - // Required. Resource name for the model evaluation. - string name = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/ModelEvaluation" - } - ]; -} - -// Request message for [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations]. -message ListModelEvaluationsRequest { - // Required. Resource name of the model to list the model evaluations for. - // If modelId is set as "-", this will list model evaluations from across all - // models of the parent location. - string parent = 1 [ - (google.api.field_behavior) = REQUIRED, - (google.api.resource_reference) = { - type: "automl.googleapis.com/Model" - } - ]; - - // An expression for filtering the results of the request. - // - // * `annotation_spec_id` - for =, != or existence. See example below for - // the last. - // - // Some examples of using the filter are: - // - // * `annotation_spec_id!=4` --> The model evaluation was done for - // annotation spec with ID different than 4. - // * `NOT annotation_spec_id:*` --> The model evaluation was done for - // aggregate of all annotation specs. - string filter = 3; - - // Requested page size. - int32 page_size = 4; - - // A token identifying a page of results for the server to return. - // Typically obtained via - // [ListModelEvaluationsResponse.next_page_token][google.cloud.automl.v1beta1.ListModelEvaluationsResponse.next_page_token] of the previous - // [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations] call. - string page_token = 6; -} - -// Response message for [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations]. -message ListModelEvaluationsResponse { - // List of model evaluations in the requested page. - repeated ModelEvaluation model_evaluation = 1; - - // A token to retrieve next page of results. - // Pass to the [ListModelEvaluationsRequest.page_token][google.cloud.automl.v1beta1.ListModelEvaluationsRequest.page_token] field of a new - // [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations] request to obtain that page. - string next_page_token = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/table_spec.proto b/google/cloud/automl_v1beta1/proto/table_spec.proto deleted file mode 100644 index bc3fc744..00000000 --- a/google/cloud/automl_v1beta1/proto/table_spec.proto +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/resource.proto"; -import "google/cloud/automl/v1beta1/io.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A specification of a relational table. -// The table's schema is represented via its child column specs. It is -// pre-populated as part of ImportData by schema inference algorithm, the -// version of which is a required parameter of ImportData InputConfig. -// Note: While working with a table, at times the schema may be -// inconsistent with the data in the table (e.g. string in a FLOAT64 column). -// The consistency validation is done upon creation of a model. -// Used by: -// * Tables -message TableSpec { - option (google.api.resource) = { - type: "automl.googleapis.com/TableSpec" - pattern: "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}" - }; - - // Output only. The resource name of the table spec. - // Form: - // - // `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/tableSpecs/{table_spec_id}` - string name = 1; - - // column_spec_id of the time column. Only used if the parent dataset's - // ml_use_column_spec_id is not set. Used to split rows into TRAIN, VALIDATE - // and TEST sets such that oldest rows go to TRAIN set, newest to TEST, and - // those in between to VALIDATE. - // Required type: TIMESTAMP. - // If both this column and ml_use_column are not set, then ML use of all rows - // will be assigned by AutoML. NOTE: Updates of this field will instantly - // affect any other users concurrently working with the dataset. - string time_column_spec_id = 2; - - // Output only. The number of rows (i.e. examples) in the table. - int64 row_count = 3; - - // Output only. The number of valid rows (i.e. without values that don't match - // DataType-s of their columns). - int64 valid_row_count = 4; - - // Output only. The number of columns of the table. That is, the number of - // child ColumnSpec-s. - int64 column_count = 7; - - // Output only. Input configs via which data currently residing in the table - // had been imported. - repeated InputConfig input_configs = 5; - - // Used to perform consistent read-modify-write updates. If not set, a blind - // "overwrite" update happens. - string etag = 6; -} diff --git a/google/cloud/automl_v1beta1/proto/tables.proto b/google/cloud/automl_v1beta1/proto/tables.proto deleted file mode 100644 index 5327f5e7..00000000 --- a/google/cloud/automl_v1beta1/proto/tables.proto +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/cloud/automl/v1beta1/column_spec.proto"; -import "google/cloud/automl/v1beta1/data_items.proto"; -import "google/cloud/automl/v1beta1/data_stats.proto"; -import "google/cloud/automl/v1beta1/ranges.proto"; -import "google/cloud/automl/v1beta1/regression.proto"; -import "google/cloud/automl/v1beta1/temporal.proto"; -import "google/protobuf/struct.proto"; -import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Metadata for a dataset used for AutoML Tables. -message TablesDatasetMetadata { - // Output only. The table_spec_id of the primary table of this dataset. - string primary_table_spec_id = 1; - - // column_spec_id of the primary table's column that should be used as the - // training & prediction target. - // This column must be non-nullable and have one of following data types - // (otherwise model creation will error): - // - // * CATEGORY - // - // * FLOAT64 - // - // If the type is CATEGORY , only up to - // 100 unique values may exist in that column across all rows. - // - // NOTE: Updates of this field will instantly affect any other users - // concurrently working with the dataset. - string target_column_spec_id = 2; - - // column_spec_id of the primary table's column that should be used as the - // weight column, i.e. the higher the value the more important the row will be - // during model training. - // Required type: FLOAT64. - // Allowed values: 0 to 10000, inclusive on both ends; 0 means the row is - // ignored for training. - // If not set all rows are assumed to have equal weight of 1. - // NOTE: Updates of this field will instantly affect any other users - // concurrently working with the dataset. - string weight_column_spec_id = 3; - - // column_spec_id of the primary table column which specifies a possible ML - // use of the row, i.e. the column will be used to split the rows into TRAIN, - // VALIDATE and TEST sets. - // Required type: STRING. - // This column, if set, must either have all of `TRAIN`, `VALIDATE`, `TEST` - // among its values, or only have `TEST`, `UNASSIGNED` values. In the latter - // case the rows with `UNASSIGNED` value will be assigned by AutoML. Note - // that if a given ml use distribution makes it impossible to create a "good" - // model, that call will error describing the issue. - // If both this column_spec_id and primary table's time_column_spec_id are not - // set, then all rows are treated as `UNASSIGNED`. - // NOTE: Updates of this field will instantly affect any other users - // concurrently working with the dataset. - string ml_use_column_spec_id = 4; - - // Output only. Correlations between - // - // [TablesDatasetMetadata.target_column_spec_id][google.cloud.automl.v1beta1.TablesDatasetMetadata.target_column_spec_id], - // and other columns of the - // - // [TablesDatasetMetadataprimary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_spec_id]. - // Only set if the target column is set. Mapping from other column spec id to - // its CorrelationStats with the target column. - // This field may be stale, see the stats_update_time field for - // for the timestamp at which these stats were last updated. - map target_column_correlations = 6; - - // Output only. The most recent timestamp when target_column_correlations - // field and all descendant ColumnSpec.data_stats and - // ColumnSpec.top_correlated_columns fields were last (re-)generated. Any - // changes that happened to the dataset afterwards are not reflected in these - // fields values. The regeneration happens in the background on a best effort - // basis. - google.protobuf.Timestamp stats_update_time = 7; -} - -// Model metadata specific to AutoML Tables. -message TablesModelMetadata { - // Additional optimization objective configuration. Required for - // `MAXIMIZE_PRECISION_AT_RECALL` and `MAXIMIZE_RECALL_AT_PRECISION`, - // otherwise unused. - oneof additional_optimization_objective_config { - // Required when optimization_objective is "MAXIMIZE_PRECISION_AT_RECALL". - // Must be between 0 and 1, inclusive. - float optimization_objective_recall_value = 17; - - // Required when optimization_objective is "MAXIMIZE_RECALL_AT_PRECISION". - // Must be between 0 and 1, inclusive. - float optimization_objective_precision_value = 18; - } - - // Column spec of the dataset's primary table's column the model is - // predicting. Snapshotted when model creation started. - // Only 3 fields are used: - // name - May be set on CreateModel, if it's not then the ColumnSpec - // corresponding to the current target_column_spec_id of the dataset - // the model is trained from is used. - // If neither is set, CreateModel will error. - // display_name - Output only. - // data_type - Output only. - ColumnSpec target_column_spec = 2; - - // Column specs of the dataset's primary table's columns, on which - // the model is trained and which are used as the input for predictions. - // The - // - // [target_column][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] - // as well as, according to dataset's state upon model creation, - // - // [weight_column][google.cloud.automl.v1beta1.TablesDatasetMetadata.weight_column_spec_id], - // and - // - // [ml_use_column][google.cloud.automl.v1beta1.TablesDatasetMetadata.ml_use_column_spec_id] - // must never be included here. - // - // Only 3 fields are used: - // - // * name - May be set on CreateModel, if set only the columns specified are - // used, otherwise all primary table's columns (except the ones listed - // above) are used for the training and prediction input. - // - // * display_name - Output only. - // - // * data_type - Output only. - repeated ColumnSpec input_feature_column_specs = 3; - - // Objective function the model is optimizing towards. The training process - // creates a model that maximizes/minimizes the value of the objective - // function over the validation set. - // - // The supported optimization objectives depend on the prediction type. - // If the field is not set, a default objective function is used. - // - // CLASSIFICATION_BINARY: - // "MAXIMIZE_AU_ROC" (default) - Maximize the area under the receiver - // operating characteristic (ROC) curve. - // "MINIMIZE_LOG_LOSS" - Minimize log loss. - // "MAXIMIZE_AU_PRC" - Maximize the area under the precision-recall curve. - // "MAXIMIZE_PRECISION_AT_RECALL" - Maximize precision for a specified - // recall value. - // "MAXIMIZE_RECALL_AT_PRECISION" - Maximize recall for a specified - // precision value. - // - // CLASSIFICATION_MULTI_CLASS : - // "MINIMIZE_LOG_LOSS" (default) - Minimize log loss. - // - // - // REGRESSION: - // "MINIMIZE_RMSE" (default) - Minimize root-mean-squared error (RMSE). - // "MINIMIZE_MAE" - Minimize mean-absolute error (MAE). - // "MINIMIZE_RMSLE" - Minimize root-mean-squared log error (RMSLE). - string optimization_objective = 4; - - // Output only. Auxiliary information for each of the - // input_feature_column_specs with respect to this particular model. - repeated TablesModelColumnInfo tables_model_column_info = 5; - - // Required. The train budget of creating this model, expressed in milli node - // hours i.e. 1,000 value in this field means 1 node hour. - // - // The training cost of the model will not exceed this budget. The final cost - // will be attempted to be close to the budget, though may end up being (even) - // noticeably smaller - at the backend's discretion. This especially may - // happen when further model training ceases to provide any improvements. - // - // If the budget is set to a value known to be insufficient to train a - // model for the given dataset, the training won't be attempted and - // will error. - // - // The train budget must be between 1,000 and 72,000 milli node hours, - // inclusive. - int64 train_budget_milli_node_hours = 6; - - // Output only. The actual training cost of the model, expressed in milli - // node hours, i.e. 1,000 value in this field means 1 node hour. Guaranteed - // to not exceed the train budget. - int64 train_cost_milli_node_hours = 7; - - // Use the entire training budget. This disables the early stopping feature. - // By default, the early stopping feature is enabled, which means that AutoML - // Tables might stop training before the entire training budget has been used. - bool disable_early_stopping = 12; -} - -// Contains annotation details specific to Tables. -message TablesAnnotation { - // Output only. A confidence estimate between 0.0 and 1.0, inclusive. A higher - // value means greater confidence in the returned value. - // For - // - // [target_column_spec][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] - // of FLOAT64 data type the score is not populated. - float score = 1; - - // Output only. Only populated when - // - // [target_column_spec][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] - // has FLOAT64 data type. An interval in which the exactly correct target - // value has 95% chance to be in. - DoubleRange prediction_interval = 4; - - // The predicted value of the row's - // - // [target_column][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec]. - // The value depends on the column's DataType: - // - // * CATEGORY - the predicted (with the above confidence `score`) CATEGORY - // value. - // - // * FLOAT64 - the predicted (with above `prediction_interval`) FLOAT64 value. - google.protobuf.Value value = 2; - - // Output only. Auxiliary information for each of the model's - // - // [input_feature_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] - // with respect to this particular prediction. - // If no other fields than - // - // [column_spec_name][google.cloud.automl.v1beta1.TablesModelColumnInfo.column_spec_name] - // and - // - // [column_display_name][google.cloud.automl.v1beta1.TablesModelColumnInfo.column_display_name] - // would be populated, then this whole field is not. - repeated TablesModelColumnInfo tables_model_column_info = 3; - - // Output only. Stores the prediction score for the baseline example, which - // is defined as the example with all values set to their baseline values. - // This is used as part of the Sampled Shapley explanation of the model's - // prediction. This field is populated only when feature importance is - // requested. For regression models, this holds the baseline prediction for - // the baseline example. For classification models, this holds the baseline - // prediction for the baseline example for the argmax class. - float baseline_score = 5; -} - -// An information specific to given column and Tables Model, in context -// of the Model and the predictions created by it. -message TablesModelColumnInfo { - // Output only. The name of the ColumnSpec describing the column. Not - // populated when this proto is outputted to BigQuery. - string column_spec_name = 1; - - // Output only. The display name of the column (same as the display_name of - // its ColumnSpec). - string column_display_name = 2; - - // Output only. When given as part of a Model (always populated): - // Measurement of how much model predictions correctness on the TEST data - // depend on values in this column. A value between 0 and 1, higher means - // higher influence. These values are normalized - for all input feature - // columns of a given model they add to 1. - // - // When given back by Predict (populated iff - // [feature_importance - // param][google.cloud.automl.v1beta1.PredictRequest.params] is set) or Batch - // Predict (populated iff - // [feature_importance][google.cloud.automl.v1beta1.PredictRequest.params] - // param is set): - // Measurement of how impactful for the prediction returned for the given row - // the value in this column was. Specifically, the feature importance - // specifies the marginal contribution that the feature made to the prediction - // score compared to the baseline score. These values are computed using the - // Sampled Shapley method. - float feature_importance = 3; -} diff --git a/google/cloud/automl_v1beta1/proto/temporal.proto b/google/cloud/automl_v1beta1/proto/temporal.proto deleted file mode 100644 index 76db8887..00000000 --- a/google/cloud/automl_v1beta1/proto/temporal.proto +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/protobuf/duration.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A time period inside of an example that has a time dimension (e.g. video). -message TimeSegment { - // Start of the time segment (inclusive), represented as the duration since - // the example start. - google.protobuf.Duration start_time_offset = 1; - - // End of the time segment (exclusive), represented as the duration since the - // example start. - google.protobuf.Duration end_time_offset = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/text.proto b/google/cloud/automl_v1beta1/proto/text.proto deleted file mode 100644 index f6f33185..00000000 --- a/google/cloud/automl_v1beta1/proto/text.proto +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "TextProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Dataset metadata for classification. -message TextClassificationDatasetMetadata { - // Required. Type of the classification problem. - ClassificationType classification_type = 1; -} - -// Model metadata that is specific to text classification. -message TextClassificationModelMetadata { - // Output only. Classification type of the dataset used to train this model. - ClassificationType classification_type = 3; -} - -// Dataset metadata that is specific to text extraction -message TextExtractionDatasetMetadata { - -} - -// Model metadata that is specific to text extraction. -message TextExtractionModelMetadata { - -} - -// Dataset metadata for text sentiment. -message TextSentimentDatasetMetadata { - // Required. A sentiment is expressed as an integer ordinal, where higher value - // means a more positive sentiment. The range of sentiments that will be used - // is between 0 and sentiment_max (inclusive on both ends), and all the values - // in the range must be represented in the dataset before a model can be - // created. - // sentiment_max value must be between 1 and 10 (inclusive). - int32 sentiment_max = 1; -} - -// Model metadata that is specific to text sentiment. -message TextSentimentModelMetadata { - -} diff --git a/google/cloud/automl_v1beta1/proto/text_extraction.proto b/google/cloud/automl_v1beta1/proto/text_extraction.proto deleted file mode 100644 index cfb0e0b3..00000000 --- a/google/cloud/automl_v1beta1/proto/text_extraction.proto +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/text_segment.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Annotation for identifying spans of text. -message TextExtractionAnnotation { - // Required. Text extraction annotations can either be a text segment or a - // text relation. - oneof annotation { - // An entity annotation will set this, which is the part of the original - // text to which the annotation pertains. - TextSegment text_segment = 3; - } - - // Output only. A confidence estimate between 0.0 and 1.0. A higher value - // means greater confidence in correctness of the annotation. - float score = 1; -} - -// Model evaluation metrics for text extraction problems. -message TextExtractionEvaluationMetrics { - // Metrics for a single confidence threshold. - message ConfidenceMetricsEntry { - // Output only. The confidence threshold value used to compute the metrics. - // Only annotations with score of at least this threshold are considered to - // be ones the model would return. - float confidence_threshold = 1; - - // Output only. Recall under the given confidence threshold. - float recall = 3; - - // Output only. Precision under the given confidence threshold. - float precision = 4; - - // Output only. The harmonic mean of recall and precision. - float f1_score = 5; - } - - // Output only. The Area under precision recall curve metric. - float au_prc = 1; - - // Output only. Metrics that have confidence thresholds. - // Precision-recall curve can be derived from it. - repeated ConfidenceMetricsEntry confidence_metrics_entries = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/text_segment.proto b/google/cloud/automl_v1beta1/proto/text_segment.proto deleted file mode 100644 index 94b17d93..00000000 --- a/google/cloud/automl_v1beta1/proto/text_segment.proto +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "TextSegmentProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// A contiguous part of a text (string), assuming it has an UTF-8 NFC encoding. -message TextSegment { - // Output only. The content of the TextSegment. - string content = 3; - - // Required. Zero-based character index of the first character of the text - // segment (counting characters from the beginning of the text). - int64 start_offset = 1; - - // Required. Zero-based character index of the first character past the end of - // the text segment (counting character from the beginning of the text). - // The character at the end_offset is NOT included in the text segment. - int64 end_offset = 2; -} diff --git a/google/cloud/automl_v1beta1/proto/text_sentiment.proto b/google/cloud/automl_v1beta1/proto/text_sentiment.proto deleted file mode 100644 index 5444c52b..00000000 --- a/google/cloud/automl_v1beta1/proto/text_sentiment.proto +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_outer_classname = "TextSentimentProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Contains annotation details specific to text sentiment. -message TextSentimentAnnotation { - // Output only. The sentiment with the semantic, as given to the - // [AutoMl.ImportData][google.cloud.automl.v1beta1.AutoMl.ImportData] when populating the dataset from which the model used - // for the prediction had been trained. - // The sentiment values are between 0 and - // Dataset.text_sentiment_dataset_metadata.sentiment_max (inclusive), - // with higher value meaning more positive sentiment. They are completely - // relative, i.e. 0 means least positive sentiment and sentiment_max means - // the most positive from the sentiments present in the train data. Therefore - // e.g. if train data had only negative sentiment, then sentiment_max, would - // be still negative (although least negative). - // The sentiment shouldn't be confused with "score" or "magnitude" - // from the previous Natural Language Sentiment Analysis API. - int32 sentiment = 1; -} - -// Model evaluation metrics for text sentiment problems. -message TextSentimentEvaluationMetrics { - // Output only. Precision. - float precision = 1; - - // Output only. Recall. - float recall = 2; - - // Output only. The harmonic mean of recall and precision. - float f1_score = 3; - - // Output only. Mean absolute error. Only set for the overall model - // evaluation, not for evaluation of a single annotation spec. - float mean_absolute_error = 4; - - // Output only. Mean squared error. Only set for the overall model - // evaluation, not for evaluation of a single annotation spec. - float mean_squared_error = 5; - - // Output only. Linear weighted kappa. Only set for the overall model - // evaluation, not for evaluation of a single annotation spec. - float linear_kappa = 6; - - // Output only. Quadratic weighted kappa. Only set for the overall model - // evaluation, not for evaluation of a single annotation spec. - float quadratic_kappa = 7; - - // Output only. Confusion matrix of the evaluation. - // Only set for the overall model evaluation, not for evaluation of a single - // annotation spec. - ClassificationEvaluationMetrics.ConfusionMatrix confusion_matrix = 8; - - // Output only. The annotation spec ids used for this evaluation. - // Deprecated . - repeated string annotation_spec_id = 9 [deprecated = true]; -} diff --git a/google/cloud/automl_v1beta1/proto/translation.proto b/google/cloud/automl_v1beta1/proto/translation.proto deleted file mode 100644 index 8585bd41..00000000 --- a/google/cloud/automl_v1beta1/proto/translation.proto +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/api/field_behavior.proto"; -import "google/cloud/automl/v1beta1/data_items.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "TranslationProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Dataset metadata that is specific to translation. -message TranslationDatasetMetadata { - // Required. The BCP-47 language code of the source language. - string source_language_code = 1 [(google.api.field_behavior) = REQUIRED]; - - // Required. The BCP-47 language code of the target language. - string target_language_code = 2 [(google.api.field_behavior) = REQUIRED]; -} - -// Evaluation metrics for the dataset. -message TranslationEvaluationMetrics { - // Output only. BLEU score. - double bleu_score = 1; - - // Output only. BLEU score for base model. - double base_bleu_score = 2; -} - -// Model metadata that is specific to translation. -message TranslationModelMetadata { - // The resource name of the model to use as a baseline to train the custom - // model. If unset, we use the default base model provided by Google - // Translate. Format: - // `projects/{project_id}/locations/{location_id}/models/{model_id}` - string base_model = 1; - - // Output only. Inferred from the dataset. - // The source languge (The BCP-47 language code) that is used for training. - string source_language_code = 2; - - // Output only. The target languge (The BCP-47 language code) that is used for - // training. - string target_language_code = 3; -} - -// Annotation details specific to translation. -message TranslationAnnotation { - // Output only . The translated content. - TextSnippet translated_content = 1; -} diff --git a/google/cloud/automl_v1beta1/proto/video.proto b/google/cloud/automl_v1beta1/proto/video.proto deleted file mode 100644 index 268ae2a8..00000000 --- a/google/cloud/automl_v1beta1/proto/video.proto +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2020 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.automl.v1beta1; - -import "google/cloud/automl/v1beta1/classification.proto"; -import "google/api/annotations.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; -option java_multiple_files = true; -option java_outer_classname = "VideoProto"; -option java_package = "com.google.cloud.automl.v1beta1"; -option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; -option ruby_package = "Google::Cloud::AutoML::V1beta1"; - -// Dataset metadata specific to video classification. -// All Video Classification datasets are treated as multi label. -message VideoClassificationDatasetMetadata { - -} - -// Dataset metadata specific to video object tracking. -message VideoObjectTrackingDatasetMetadata { - -} - -// Model metadata specific to video classification. -message VideoClassificationModelMetadata { - -} - -// Model metadata specific to video object tracking. -message VideoObjectTrackingModelMetadata { - -} diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index b7a10974..5c6d1f5b 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -28,8 +28,8 @@ from google.auth import credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore +from google.api_core import operation +from google.api_core import operation_async from google.cloud.automl_v1beta1.services.auto_ml import pagers from google.cloud.automl_v1beta1.types import annotation_spec from google.cloud.automl_v1beta1.types import classification @@ -87,14 +87,13 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT - column_spec_path = staticmethod(AutoMlClient.column_spec_path) - parse_column_spec_path = staticmethod(AutoMlClient.parse_column_spec_path) dataset_path = staticmethod(AutoMlClient.dataset_path) - parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) + model_path = staticmethod(AutoMlClient.model_path) - parse_model_path = staticmethod(AutoMlClient.parse_model_path) + + column_spec_path = staticmethod(AutoMlClient.column_spec_path) + table_spec_path = staticmethod(AutoMlClient.table_spec_path) - parse_table_spec_path = staticmethod(AutoMlClient.parse_table_spec_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file @@ -125,19 +124,16 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1beta1/services/auto_ml/client.py b/google/cloud/automl_v1beta1/services/auto_ml/client.py index 6ae4f4c2..9416b524 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/client.py @@ -16,24 +16,22 @@ # from collections import OrderedDict -from distutils import util import os import re -from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union +from typing import Callable, Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore +import google.api_core.client_options as ClientOptions # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore +from google.api_core import operation +from google.api_core import operation_async from google.cloud.automl_v1beta1.services.auto_ml import pagers from google.cloud.automl_v1beta1.types import annotation_spec from google.cloud.automl_v1beta1.types import classification @@ -246,9 +244,9 @@ def parse_table_spec_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, - transport: Union[str, AutoMlTransport, None] = None, - client_options: Optional[client_options_lib.ClientOptions] = None, + credentials: credentials.Credentials = None, + transport: Union[str, AutoMlTransport] = None, + client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the auto ml client. @@ -262,22 +260,19 @@ def __init__( transport (Union[str, ~.AutoMlTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the - client. It won't take effect if a ``transport`` instance is provided. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -289,47 +284,29 @@ def __init__( creation failed for any reason. """ if isinstance(client_options, dict): - client_options = client_options_lib.from_dict(client_options) + client_options = ClientOptions.from_dict(client_options) if client_options is None: - client_options = client_options_lib.ClientOptions() + client_options = ClientOptions.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) - ) - - ssl_credentials = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - is_mtls = True - else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if client_options.api_endpoint is None: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT + client_options.api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT + client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT + has_client_cert_source = ( + client_options.client_cert_source is not None + or mtls.has_default_client_cert_source() + ) + client_options.api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if has_client_cert_source + else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -353,9 +330,10 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=api_endpoint, + host=client_options.api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + api_mtls_endpoint=client_options.api_endpoint, + client_cert_source=client_options.client_cert_source, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py index 642c9f7b..d50f2201 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth # type: ignore +from google import auth from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py index a8cb2fd7..a3c183e4 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py @@ -15,7 +15,6 @@ # limitations under the License. # -import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -25,6 +24,7 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore + import grpc # type: ignore from google.cloud.automl_v1beta1.types import annotation_spec @@ -81,7 +81,6 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -102,16 +101,14 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -134,11 +131,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -169,23 +161,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) self._stubs = {} # type: Dict[str, Callable] @@ -251,6 +226,13 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py index a977ad45..c8d24dad 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py @@ -15,13 +15,11 @@ # limitations under the License. # -import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -125,7 +123,6 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -147,16 +144,14 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -179,22 +174,12 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -214,23 +199,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) # Run the base constructor. super().__init__( @@ -251,6 +219,13 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py index c204325b..cd313402 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py @@ -28,8 +28,8 @@ from google.auth import credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore +from google.api_core import operation +from google.api_core import operation_async from google.cloud.automl_v1beta1.types import annotation_payload from google.cloud.automl_v1beta1.types import data_items from google.cloud.automl_v1beta1.types import io @@ -82,19 +82,16 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1beta1/services/prediction_service/client.py b/google/cloud/automl_v1beta1/services/prediction_service/client.py index 78ec510c..81cb0649 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/client.py @@ -16,24 +16,22 @@ # from collections import OrderedDict -from distutils import util import os import re -from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union +from typing import Callable, Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore +import google.api_core.client_options as ClientOptions # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore +from google.api_core import operation +from google.api_core import operation_async from google.cloud.automl_v1beta1.types import annotation_payload from google.cloud.automl_v1beta1.types import data_items from google.cloud.automl_v1beta1.types import io @@ -144,9 +142,9 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, - transport: Union[str, PredictionServiceTransport, None] = None, - client_options: Optional[client_options_lib.ClientOptions] = None, + credentials: credentials.Credentials = None, + transport: Union[str, PredictionServiceTransport] = None, + client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the prediction service client. @@ -160,22 +158,19 @@ def __init__( transport (Union[str, ~.PredictionServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the - client. It won't take effect if a ``transport`` instance is provided. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + default endpoint provided by the client. GOOGLE_API_USE_MTLS environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto switch to the - default mTLS endpoint if client certificate is present, this is - the default value). However, the ``api_endpoint`` property takes - precedence if provided. - (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide client certificate for mutual TLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -187,47 +182,29 @@ def __init__( creation failed for any reason. """ if isinstance(client_options, dict): - client_options = client_options_lib.from_dict(client_options) + client_options = ClientOptions.from_dict(client_options) if client_options is None: - client_options = client_options_lib.ClientOptions() + client_options = ClientOptions.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) - ) - - ssl_credentials = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - is_mtls = True - else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if client_options.api_endpoint is None: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT + client_options.api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT + client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT + has_client_cert_source = ( + client_options.client_cert_source is not None + or mtls.has_default_client_cert_source() + ) + client_options.api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if has_client_cert_source + else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -251,9 +228,10 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=api_endpoint, + host=client_options.api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + api_mtls_endpoint=client_options.api_endpoint, + client_cert_source=client_options.client_cert_source, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py index 04857f4c..bb674eca 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth # type: ignore +from google import auth from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py index 3c484247..9bc30cdd 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py @@ -15,7 +15,6 @@ # limitations under the License. # -import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -25,6 +24,7 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore + import grpc # type: ignore from google.cloud.automl_v1beta1.types import prediction_service @@ -61,7 +61,6 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -82,16 +81,14 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -114,11 +111,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -149,23 +141,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) self._stubs = {} # type: Dict[str, Callable] @@ -231,6 +206,13 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py index 0b1bb638..2c7d9712 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py @@ -15,13 +15,11 @@ # limitations under the License. # -import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -105,7 +103,6 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -127,16 +124,14 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -159,22 +154,12 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -194,23 +179,6 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) # Run the base constructor. super().__init__( @@ -231,6 +199,13 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/types/classification.py b/google/cloud/automl_v1beta1/types/classification.py index 4b5e5a2a..8c879bf2 100644 --- a/google/cloud/automl_v1beta1/types/classification.py +++ b/google/cloud/automl_v1beta1/types/classification.py @@ -60,7 +60,7 @@ class VideoClassificationAnnotation(proto.Message): r"""Contains annotation details specific to video classification. Attributes: - type_ (str): + type (str): Output only. Expresses the type of video classification. Possible values: @@ -96,7 +96,7 @@ class VideoClassificationAnnotation(proto.Message): to which the annotation applies. """ - type_ = proto.Field(proto.STRING, number=1) + type = proto.Field(proto.STRING, number=1) classification_annotation = proto.Field( proto.MESSAGE, number=2, message=ClassificationAnnotation, diff --git a/google/cloud/automl_v1beta1/types/data_stats.py b/google/cloud/automl_v1beta1/types/data_stats.py index 4405185f..4ae40fc8 100644 --- a/google/cloud/automl_v1beta1/types/data_stats.py +++ b/google/cloud/automl_v1beta1/types/data_stats.py @@ -115,9 +115,9 @@ class HistogramBucket(proto.Message): r"""A bucket of a histogram. Attributes: - min_ (float): + min (float): The minimum value of the bucket, inclusive. - max_ (float): + max (float): The maximum value of the bucket, exclusive unless max = ``"Infinity"``, in which case it's inclusive. count (int): @@ -125,9 +125,9 @@ class HistogramBucket(proto.Message): bucket, i.e. are between min and max values. """ - min_ = proto.Field(proto.DOUBLE, number=1) + min = proto.Field(proto.DOUBLE, number=1) - max_ = proto.Field(proto.DOUBLE, number=2) + max = proto.Field(proto.DOUBLE, number=2) count = proto.Field(proto.INT64, number=3) diff --git a/noxfile.py b/noxfile.py index 709afdde..9c69b3b7 100644 --- a/noxfile.py +++ b/noxfile.py @@ -74,6 +74,7 @@ def default(session): session.install("mock", "pytest", "pytest-cov") session.install("-e", ".[pandas,storage]") + session.install("proto-plus==1.8.1") # Run py.test against the unit tests. session.run( @@ -198,3 +199,36 @@ def docfx(session): os.path.join("docs", ""), os.path.join("docs", "_build", "html", ""), ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docfx(session): + """Build the docfx yaml files for this library.""" + + session.install("-e", ".[pandas,storage]") + session.install("sphinx<3.0.0", "alabaster", "recommonmark", "sphinx-docfx-yaml") + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-D", + ( + "extensions=sphinx.ext.autodoc," + "sphinx.ext.autosummary," + "docfx_yaml.extension," + "sphinx.ext.intersphinx," + "sphinx.ext.coverage," + "sphinx.ext.napoleon," + "sphinx.ext.todo," + "sphinx.ext.viewcode," + "recommonmark" + ), + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) diff --git a/synth.metadata b/synth.metadata index 49639732..6c3bc216 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,16 +3,16 @@ { "git": { "name": ".", - "remote": "https://github.com/googleapis/python-automl.git", - "sha": "8c7d54872a6e5628171f160e1a39a067d5f46563" + "remote": "git@github.com:googleapis/python-automl", + "sha": "9b218b1f1cd0caef664e51064baf5f4af07a97c1" } }, { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "7e377ce8f06ced48a79b45d97eebccb8a51f1e28", - "internalRef": "333323660" + "sha": "17de2b31f9450385e739bedeeaac6e1ec4f239a8", + "internalRef": "327504150" } }, { @@ -49,221 +49,5 @@ "generator": "bazel" } } - ], - "generatedFiles": [ - ".coveragerc", - ".flake8", - ".github/CONTRIBUTING.md", - ".github/ISSUE_TEMPLATE/bug_report.md", - ".github/ISSUE_TEMPLATE/feature_request.md", - ".github/ISSUE_TEMPLATE/support_request.md", - ".github/PULL_REQUEST_TEMPLATE.md", - ".github/release-please.yml", - ".gitignore", - ".kokoro/build.sh", - ".kokoro/continuous/common.cfg", - ".kokoro/continuous/continuous.cfg", - ".kokoro/docker/docs/Dockerfile", - ".kokoro/docker/docs/fetch_gpg_keys.sh", - ".kokoro/docs/common.cfg", - ".kokoro/docs/docs-presubmit.cfg", - ".kokoro/docs/docs.cfg", - ".kokoro/presubmit/common.cfg", - ".kokoro/presubmit/presubmit.cfg", - ".kokoro/publish-docs.sh", - ".kokoro/release.sh", - ".kokoro/release/common.cfg", - ".kokoro/release/release.cfg", - ".kokoro/samples/lint/common.cfg", - ".kokoro/samples/lint/continuous.cfg", - ".kokoro/samples/lint/periodic.cfg", - ".kokoro/samples/lint/presubmit.cfg", - ".kokoro/samples/python3.6/common.cfg", - ".kokoro/samples/python3.6/continuous.cfg", - ".kokoro/samples/python3.6/periodic.cfg", - ".kokoro/samples/python3.6/presubmit.cfg", - ".kokoro/samples/python3.7/common.cfg", - ".kokoro/samples/python3.7/continuous.cfg", - ".kokoro/samples/python3.7/periodic.cfg", - ".kokoro/samples/python3.7/presubmit.cfg", - ".kokoro/samples/python3.8/common.cfg", - ".kokoro/samples/python3.8/continuous.cfg", - ".kokoro/samples/python3.8/periodic.cfg", - ".kokoro/samples/python3.8/presubmit.cfg", - ".kokoro/test-samples.sh", - ".kokoro/trampoline.sh", - ".kokoro/trampoline_v2.sh", - ".trampolinerc", - "CODE_OF_CONDUCT.md", - "CONTRIBUTING.rst", - "LICENSE", - "MANIFEST.in", - "docs/_static/custom.css", - "docs/_templates/layout.html", - "docs/automl_v1/services.rst", - "docs/automl_v1/types.rst", - "docs/automl_v1beta1/services.rst", - "docs/automl_v1beta1/types.rst", - "docs/conf.py", - "docs/multiprocessing.rst", - "google/cloud/automl/__init__.py", - "google/cloud/automl/py.typed", - "google/cloud/automl_v1/__init__.py", - "google/cloud/automl_v1/proto/annotation_payload.proto", - "google/cloud/automl_v1/proto/annotation_spec.proto", - "google/cloud/automl_v1/proto/classification.proto", - "google/cloud/automl_v1/proto/data_items.proto", - "google/cloud/automl_v1/proto/dataset.proto", - "google/cloud/automl_v1/proto/detection.proto", - "google/cloud/automl_v1/proto/geometry.proto", - "google/cloud/automl_v1/proto/image.proto", - "google/cloud/automl_v1/proto/io.proto", - "google/cloud/automl_v1/proto/model.proto", - "google/cloud/automl_v1/proto/model_evaluation.proto", - "google/cloud/automl_v1/proto/operations.proto", - "google/cloud/automl_v1/proto/prediction_service.proto", - "google/cloud/automl_v1/proto/service.proto", - "google/cloud/automl_v1/proto/text.proto", - "google/cloud/automl_v1/proto/text_extraction.proto", - "google/cloud/automl_v1/proto/text_segment.proto", - "google/cloud/automl_v1/proto/text_sentiment.proto", - "google/cloud/automl_v1/proto/translation.proto", - "google/cloud/automl_v1/py.typed", - "google/cloud/automl_v1/services/__init__.py", - "google/cloud/automl_v1/services/auto_ml/__init__.py", - "google/cloud/automl_v1/services/auto_ml/async_client.py", - "google/cloud/automl_v1/services/auto_ml/client.py", - "google/cloud/automl_v1/services/auto_ml/pagers.py", - "google/cloud/automl_v1/services/auto_ml/transports/__init__.py", - "google/cloud/automl_v1/services/auto_ml/transports/base.py", - "google/cloud/automl_v1/services/auto_ml/transports/grpc.py", - "google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py", - "google/cloud/automl_v1/services/prediction_service/__init__.py", - "google/cloud/automl_v1/services/prediction_service/async_client.py", - "google/cloud/automl_v1/services/prediction_service/client.py", - "google/cloud/automl_v1/services/prediction_service/transports/__init__.py", - "google/cloud/automl_v1/services/prediction_service/transports/base.py", - "google/cloud/automl_v1/services/prediction_service/transports/grpc.py", - "google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py", - "google/cloud/automl_v1/types/__init__.py", - "google/cloud/automl_v1/types/annotation_payload.py", - "google/cloud/automl_v1/types/annotation_spec.py", - "google/cloud/automl_v1/types/classification.py", - "google/cloud/automl_v1/types/data_items.py", - "google/cloud/automl_v1/types/dataset.py", - "google/cloud/automl_v1/types/detection.py", - "google/cloud/automl_v1/types/geometry.py", - "google/cloud/automl_v1/types/image.py", - "google/cloud/automl_v1/types/io.py", - "google/cloud/automl_v1/types/model.py", - "google/cloud/automl_v1/types/model_evaluation.py", - "google/cloud/automl_v1/types/operations.py", - "google/cloud/automl_v1/types/prediction_service.py", - "google/cloud/automl_v1/types/service.py", - "google/cloud/automl_v1/types/text.py", - "google/cloud/automl_v1/types/text_extraction.py", - "google/cloud/automl_v1/types/text_segment.py", - "google/cloud/automl_v1/types/text_sentiment.py", - "google/cloud/automl_v1/types/translation.py", - "google/cloud/automl_v1beta1/__init__.py", - "google/cloud/automl_v1beta1/proto/annotation_payload.proto", - "google/cloud/automl_v1beta1/proto/annotation_spec.proto", - "google/cloud/automl_v1beta1/proto/classification.proto", - "google/cloud/automl_v1beta1/proto/column_spec.proto", - "google/cloud/automl_v1beta1/proto/data_items.proto", - "google/cloud/automl_v1beta1/proto/data_stats.proto", - "google/cloud/automl_v1beta1/proto/data_types.proto", - "google/cloud/automl_v1beta1/proto/dataset.proto", - "google/cloud/automl_v1beta1/proto/detection.proto", - "google/cloud/automl_v1beta1/proto/geometry.proto", - "google/cloud/automl_v1beta1/proto/image.proto", - "google/cloud/automl_v1beta1/proto/io.proto", - "google/cloud/automl_v1beta1/proto/model.proto", - "google/cloud/automl_v1beta1/proto/model_evaluation.proto", - "google/cloud/automl_v1beta1/proto/operations.proto", - "google/cloud/automl_v1beta1/proto/prediction_service.proto", - "google/cloud/automl_v1beta1/proto/ranges.proto", - "google/cloud/automl_v1beta1/proto/regression.proto", - "google/cloud/automl_v1beta1/proto/service.proto", - "google/cloud/automl_v1beta1/proto/table_spec.proto", - "google/cloud/automl_v1beta1/proto/tables.proto", - "google/cloud/automl_v1beta1/proto/temporal.proto", - "google/cloud/automl_v1beta1/proto/text.proto", - "google/cloud/automl_v1beta1/proto/text_extraction.proto", - "google/cloud/automl_v1beta1/proto/text_segment.proto", - "google/cloud/automl_v1beta1/proto/text_sentiment.proto", - "google/cloud/automl_v1beta1/proto/translation.proto", - "google/cloud/automl_v1beta1/proto/video.proto", - "google/cloud/automl_v1beta1/py.typed", - "google/cloud/automl_v1beta1/services/__init__.py", - "google/cloud/automl_v1beta1/services/auto_ml/__init__.py", - "google/cloud/automl_v1beta1/services/auto_ml/async_client.py", - "google/cloud/automl_v1beta1/services/auto_ml/client.py", - "google/cloud/automl_v1beta1/services/auto_ml/pagers.py", - "google/cloud/automl_v1beta1/services/auto_ml/transports/__init__.py", - "google/cloud/automl_v1beta1/services/auto_ml/transports/base.py", - "google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py", - "google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py", - "google/cloud/automl_v1beta1/services/prediction_service/__init__.py", - "google/cloud/automl_v1beta1/services/prediction_service/async_client.py", - "google/cloud/automl_v1beta1/services/prediction_service/client.py", - "google/cloud/automl_v1beta1/services/prediction_service/transports/__init__.py", - "google/cloud/automl_v1beta1/services/prediction_service/transports/base.py", - "google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py", - "google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py", - "google/cloud/automl_v1beta1/types/__init__.py", - "google/cloud/automl_v1beta1/types/annotation_payload.py", - "google/cloud/automl_v1beta1/types/annotation_spec.py", - "google/cloud/automl_v1beta1/types/classification.py", - "google/cloud/automl_v1beta1/types/column_spec.py", - "google/cloud/automl_v1beta1/types/data_items.py", - "google/cloud/automl_v1beta1/types/data_stats.py", - "google/cloud/automl_v1beta1/types/data_types.py", - "google/cloud/automl_v1beta1/types/dataset.py", - "google/cloud/automl_v1beta1/types/detection.py", - "google/cloud/automl_v1beta1/types/geometry.py", - "google/cloud/automl_v1beta1/types/image.py", - "google/cloud/automl_v1beta1/types/io.py", - "google/cloud/automl_v1beta1/types/model.py", - "google/cloud/automl_v1beta1/types/model_evaluation.py", - "google/cloud/automl_v1beta1/types/operations.py", - "google/cloud/automl_v1beta1/types/prediction_service.py", - "google/cloud/automl_v1beta1/types/ranges.py", - "google/cloud/automl_v1beta1/types/regression.py", - "google/cloud/automl_v1beta1/types/service.py", - "google/cloud/automl_v1beta1/types/table_spec.py", - "google/cloud/automl_v1beta1/types/tables.py", - "google/cloud/automl_v1beta1/types/temporal.py", - "google/cloud/automl_v1beta1/types/text.py", - "google/cloud/automl_v1beta1/types/text_extraction.py", - "google/cloud/automl_v1beta1/types/text_segment.py", - "google/cloud/automl_v1beta1/types/text_sentiment.py", - "google/cloud/automl_v1beta1/types/translation.py", - "google/cloud/automl_v1beta1/types/video.py", - "mypy.ini", - "noxfile.py", - "renovate.json", - "samples/AUTHORING_GUIDE.md", - "samples/CONTRIBUTING.md", - "samples/beta/noxfile.py", - "samples/snippets/noxfile.py", - "samples/tables/noxfile.py", - "scripts/decrypt-secrets.sh", - "scripts/fixup_automl_v1_keywords.py", - "scripts/fixup_automl_v1beta1_keywords.py", - "scripts/readme-gen/readme_gen.py", - "scripts/readme-gen/templates/README.tmpl.rst", - "scripts/readme-gen/templates/auth.tmpl.rst", - "scripts/readme-gen/templates/auth_api_key.tmpl.rst", - "scripts/readme-gen/templates/install_deps.tmpl.rst", - "scripts/readme-gen/templates/install_portaudio.tmpl.rst", - "setup.cfg", - "testing/.gitignore", - "tests/unit/gapic/automl_v1/__init__.py", - "tests/unit/gapic/automl_v1/test_auto_ml.py", - "tests/unit/gapic/automl_v1/test_prediction_service.py", - "tests/unit/gapic/automl_v1beta1/__init__.py", - "tests/unit/gapic/automl_v1beta1/test_auto_ml.py", - "tests/unit/gapic/automl_v1beta1/test_prediction_service.py" ] } \ No newline at end of file diff --git a/tests/unit/gapic/automl_v1/test_auto_ml.py b/tests/unit/gapic/automl_v1/test_auto_ml.py index a11480cd..42ad394e 100644 --- a/tests/unit/gapic/automl_v1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1/test_auto_ml.py @@ -31,7 +31,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.api_core import operation_async # type: ignore +from google.api_core import operation_async from google.api_core import operations_v1 from google.auth import credentials from google.auth.exceptions import MutualTLSChannelError @@ -158,14 +158,15 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -174,14 +175,15 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -190,171 +192,95 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,use_client_cert_env", - [ - (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "true"), - ( - AutoMlAsyncClient, - transports.AutoMlGrpcAsyncIOTransport, - "grpc_asyncio", - "true", - ), - (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "false"), - ( - AutoMlAsyncClient, - transports.AutoMlGrpcAsyncIOTransport, - "grpc_asyncio", - "false", - ), - ], -) -@mock.patch.object( - AutoMlClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlClient) -) -@mock.patch.object( - AutoMlAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlAsyncClient) -) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_auto_ml_client_mtls_env_auto( - client_class, transport_class, transport_name, use_client_cert_env -): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=client_cert_source_callback, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and default_client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): patched.return_value = None - client = client_class(client_options=options) - - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT - + client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=expected_host, + host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", but client_cert_source and default_client_cert_source are None. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -377,7 +303,8 @@ def test_auto_ml_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -403,7 +330,8 @@ def test_auto_ml_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -420,7 +348,8 @@ def test_auto_ml_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -1109,8 +1038,8 @@ def test_list_datasets_pages(): RuntimeError, ) pages = list(client.list_datasets(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -1174,10 +1103,10 @@ async def test_list_datasets_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_datasets(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_datasets(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_update_dataset( @@ -2933,8 +2862,8 @@ def test_list_models_pages(): RuntimeError, ) pages = list(client.list_models(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -2990,10 +2919,10 @@ async def test_list_models_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_models(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_models(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelRequest): @@ -4530,8 +4459,8 @@ def test_list_model_evaluations_pages(): RuntimeError, ) pages = list(client.list_model_evaluations(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -4615,10 +4544,10 @@ async def test_list_model_evaluations_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_model_evaluations(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_model_evaluations(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_credentials_transport_error(): @@ -4675,18 +4604,6 @@ def test_transport_get_channel(): assert channel -@pytest.mark.parametrize( - "transport_class", - [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4763,17 +4680,6 @@ def test_auto_ml_base_transport_with_credentials_file(): ) -def test_auto_ml_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(auth, "default") as adc, mock.patch( - "google.cloud.automl_v1.services.auto_ml.transports.AutoMlTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) - transport = transports.AutoMlTransport() - adc.assert_called_once() - - def test_auto_ml_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -4822,102 +4728,179 @@ def test_auto_ml_host_with_port(): def test_auto_ml_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called def test_auto_ml_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_auto_ml_grpc_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.AutoMlGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.AutoMlGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_auto_ml_transport_channel_mtls_with_client_cert_source(transport_class): - with mock.patch( - "grpc.ssl_channel_credentials", autospec=True - ) as grpc_ssl_channel_cred: - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_auto_ml_grpc_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.AutoMlGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_auto_ml_transport_channel_mtls_with_adc(transport_class): +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + mock_cred = mock.Mock() + transport = transports.AutoMlGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_auto_ml_grpc_lro_client(): @@ -4946,53 +4929,53 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_dataset_path(): +def test_model_path(): project = "squid" location = "clam" - dataset = "whelk" + model = "whelk" - expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( - project=project, location=location, dataset=dataset, + expected = "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, ) - actual = AutoMlClient.dataset_path(project, location, dataset) + actual = AutoMlClient.model_path(project, location, model) assert expected == actual -def test_parse_dataset_path(): +def test_parse_model_path(): expected = { "project": "octopus", "location": "oyster", - "dataset": "nudibranch", + "model": "nudibranch", } - path = AutoMlClient.dataset_path(**expected) + path = AutoMlClient.model_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_dataset_path(path) + actual = AutoMlClient.parse_model_path(path) assert expected == actual -def test_model_path(): +def test_dataset_path(): project = "squid" location = "clam" - model = "whelk" + dataset = "whelk" - expected = "projects/{project}/locations/{location}/models/{model}".format( - project=project, location=location, model=model, + expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( + project=project, location=location, dataset=dataset, ) - actual = AutoMlClient.model_path(project, location, model) + actual = AutoMlClient.dataset_path(project, location, dataset) assert expected == actual -def test_parse_model_path(): +def test_parse_dataset_path(): expected = { "project": "octopus", "location": "oyster", - "model": "nudibranch", + "dataset": "nudibranch", } - path = AutoMlClient.model_path(**expected) + path = AutoMlClient.dataset_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_model_path(path) + actual = AutoMlClient.parse_dataset_path(path) assert expected == actual diff --git a/tests/unit/gapic/automl_v1/test_prediction_service.py b/tests/unit/gapic/automl_v1/test_prediction_service.py index fd886203..a0087eae 100644 --- a/tests/unit/gapic/automl_v1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1/test_prediction_service.py @@ -31,7 +31,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.api_core import operation_async # type: ignore +from google.api_core import operation_async from google.api_core import operations_v1 from google.auth import credentials from google.auth.exceptions import MutualTLSChannelError @@ -167,14 +167,15 @@ def test_prediction_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -183,14 +184,15 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -199,185 +201,95 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,use_client_cert_env", - [ - ( - PredictionServiceClient, - transports.PredictionServiceGrpcTransport, - "grpc", - "true", - ), - ( - PredictionServiceAsyncClient, - transports.PredictionServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "true", - ), - ( - PredictionServiceClient, - transports.PredictionServiceGrpcTransport, - "grpc", - "false", - ), - ( - PredictionServiceAsyncClient, - transports.PredictionServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "false", - ), - ], -) -@mock.patch.object( - PredictionServiceClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(PredictionServiceClient), -) -@mock.patch.object( - PredictionServiceAsyncClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(PredictionServiceAsyncClient), -) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_prediction_service_client_mtls_env_auto( - client_class, transport_class, transport_name, use_client_cert_env -): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=client_cert_source_callback, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and default_client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): patched.return_value = None - client = client_class(client_options=options) - - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT - + client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=expected_host, + host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", but client_cert_source and default_client_cert_source are None. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -404,7 +316,8 @@ def test_prediction_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -434,7 +347,8 @@ def test_prediction_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -453,7 +367,8 @@ def test_prediction_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -989,21 +904,6 @@ def test_transport_get_channel(): assert channel -@pytest.mark.parametrize( - "transport_class", - [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -1064,17 +964,6 @@ def test_prediction_service_base_transport_with_credentials_file(): ) -def test_prediction_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(auth, "default") as adc, mock.patch( - "google.cloud.automl_v1.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) - transport = transports.PredictionServiceTransport() - adc.assert_called_once() - - def test_prediction_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -1123,110 +1012,179 @@ def test_prediction_service_host_with_port(): def test_prediction_service_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called def test_prediction_service_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_prediction_service_grpc_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.PredictionServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.PredictionServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, - ], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_prediction_service_transport_channel_mtls_with_client_cert_source( - transport_class, +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_prediction_service_grpc_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint ): - with mock.patch( - "grpc.ssl_channel_credentials", autospec=True - ) as grpc_ssl_channel_cred: - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.PredictionServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, - ], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_prediction_service_transport_channel_mtls_with_adc(transport_class): +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + mock_cred = mock.Mock() + transport = transports.PredictionServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_prediction_service_grpc_lro_client(): diff --git a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py index 09cb0749..2464c824 100644 --- a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py @@ -31,7 +31,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.api_core import operation_async # type: ignore +from google.api_core import operation_async from google.api_core import operations_v1 from google.auth import credentials from google.auth.exceptions import MutualTLSChannelError @@ -168,14 +168,15 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -184,14 +185,15 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -200,171 +202,95 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,use_client_cert_env", - [ - (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "true"), - ( - AutoMlAsyncClient, - transports.AutoMlGrpcAsyncIOTransport, - "grpc_asyncio", - "true", - ), - (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "false"), - ( - AutoMlAsyncClient, - transports.AutoMlGrpcAsyncIOTransport, - "grpc_asyncio", - "false", - ), - ], -) -@mock.patch.object( - AutoMlClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlClient) -) -@mock.patch.object( - AutoMlAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlAsyncClient) -) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_auto_ml_client_mtls_env_auto( - client_class, transport_class, transport_name, use_client_cert_env -): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=client_cert_source_callback, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and default_client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): patched.return_value = None - client = client_class(client_options=options) - - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT - + client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=expected_host, + host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", but client_cert_source and default_client_cert_source are None. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -387,7 +313,8 @@ def test_auto_ml_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -413,7 +340,8 @@ def test_auto_ml_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -430,7 +358,8 @@ def test_auto_ml_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -1150,8 +1079,8 @@ def test_list_datasets_pages(): RuntimeError, ) pages = list(client.list_datasets(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -1215,10 +1144,10 @@ async def test_list_datasets_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_datasets(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_datasets(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_update_dataset( @@ -2782,8 +2711,8 @@ def test_list_table_specs_pages(): RuntimeError, ) pages = list(client.list_table_specs(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -2855,10 +2784,10 @@ async def test_list_table_specs_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_table_specs(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_table_specs(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_update_table_spec( @@ -3565,8 +3494,8 @@ def test_list_column_specs_pages(): RuntimeError, ) pages = list(client.list_column_specs(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -3638,10 +3567,10 @@ async def test_list_column_specs_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_column_specs(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_column_specs(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_update_column_spec( @@ -4526,8 +4455,8 @@ def test_list_models_pages(): RuntimeError, ) pages = list(client.list_models(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -4583,10 +4512,10 @@ async def test_list_models_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_models(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_models(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelRequest): @@ -6084,8 +6013,8 @@ def test_list_model_evaluations_pages(): RuntimeError, ) pages = list(client.list_model_evaluations(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token @pytest.mark.asyncio @@ -6169,10 +6098,10 @@ async def test_list_model_evaluations_async_pages(): RuntimeError, ) pages = [] - async for page_ in (await client.list_model_evaluations(request={})).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + async for page in (await client.list_model_evaluations(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token def test_credentials_transport_error(): @@ -6229,18 +6158,6 @@ def test_transport_get_channel(): assert channel -@pytest.mark.parametrize( - "transport_class", - [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -6323,17 +6240,6 @@ def test_auto_ml_base_transport_with_credentials_file(): ) -def test_auto_ml_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(auth, "default") as adc, mock.patch( - "google.cloud.automl_v1beta1.services.auto_ml.transports.AutoMlTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) - transport = transports.AutoMlTransport() - adc.assert_called_once() - - def test_auto_ml_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -6382,102 +6288,179 @@ def test_auto_ml_host_with_port(): def test_auto_ml_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called def test_auto_ml_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_auto_ml_grpc_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.AutoMlGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.AutoMlGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_auto_ml_transport_channel_mtls_with_client_cert_source(transport_class): - with mock.patch( - "grpc.ssl_channel_credentials", autospec=True - ) as grpc_ssl_channel_cred: - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_auto_ml_grpc_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.AutoMlGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_auto_ml_transport_channel_mtls_with_adc(transport_class): +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + mock_cred = mock.Mock() + transport = transports.AutoMlGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_auto_ml_grpc_lro_client(): @@ -6506,41 +6489,6 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_column_spec_path(): - project = "squid" - location = "clam" - dataset = "whelk" - table_spec = "octopus" - column_spec = "oyster" - - expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}".format( - project=project, - location=location, - dataset=dataset, - table_spec=table_spec, - column_spec=column_spec, - ) - actual = AutoMlClient.column_spec_path( - project, location, dataset, table_spec, column_spec - ) - assert expected == actual - - -def test_parse_column_spec_path(): - expected = { - "project": "nudibranch", - "location": "cuttlefish", - "dataset": "mussel", - "table_spec": "winkle", - "column_spec": "nautilus", - } - path = AutoMlClient.column_spec_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_column_spec_path(path) - assert expected == actual - - def test_dataset_path(): project = "squid" location = "clam" @@ -6591,6 +6539,41 @@ def test_parse_model_path(): assert expected == actual +def test_column_spec_path(): + project = "squid" + location = "clam" + dataset = "whelk" + table_spec = "octopus" + column_spec = "oyster" + + expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}".format( + project=project, + location=location, + dataset=dataset, + table_spec=table_spec, + column_spec=column_spec, + ) + actual = AutoMlClient.column_spec_path( + project, location, dataset, table_spec, column_spec + ) + assert expected == actual + + +def test_parse_column_spec_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "dataset": "mussel", + "table_spec": "winkle", + "column_spec": "nautilus", + } + path = AutoMlClient.column_spec_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_column_spec_path(path) + assert expected == actual + + def test_table_spec_path(): project = "squid" location = "clam" diff --git a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py index 44c966c5..c21f17b9 100644 --- a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py @@ -31,7 +31,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.api_core import operation_async # type: ignore +from google.api_core import operation_async from google.api_core import operations_v1 from google.auth import credentials from google.auth.exceptions import MutualTLSChannelError @@ -170,14 +170,15 @@ def test_prediction_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -186,14 +187,15 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -202,185 +204,95 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,use_client_cert_env", - [ - ( - PredictionServiceClient, - transports.PredictionServiceGrpcTransport, - "grpc", - "true", - ), - ( - PredictionServiceAsyncClient, - transports.PredictionServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "true", - ), - ( - PredictionServiceClient, - transports.PredictionServiceGrpcTransport, - "grpc", - "false", - ), - ( - PredictionServiceAsyncClient, - transports.PredictionServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "false", - ), - ], -) -@mock.patch.object( - PredictionServiceClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(PredictionServiceClient), -) -@mock.patch.object( - PredictionServiceAsyncClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(PredictionServiceAsyncClient), -) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_prediction_service_client_mtls_env_auto( - client_class, transport_class, transport_name, use_client_cert_env -): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=client_cert_source_callback, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and default_client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): patched.return_value = None - client = client_class(client_options=options) - - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT - + client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=expected_host, + host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", but client_cert_source and default_client_cert_source are None. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - ssl_channel_credentials=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -407,7 +319,8 @@ def test_prediction_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -437,7 +350,8 @@ def test_prediction_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -456,7 +370,8 @@ def test_prediction_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -992,21 +907,6 @@ def test_transport_get_channel(): assert channel -@pytest.mark.parametrize( - "transport_class", - [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -1067,17 +967,6 @@ def test_prediction_service_base_transport_with_credentials_file(): ) -def test_prediction_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(auth, "default") as adc, mock.patch( - "google.cloud.automl_v1beta1.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) - transport = transports.PredictionServiceTransport() - adc.assert_called_once() - - def test_prediction_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -1126,110 +1015,179 @@ def test_prediction_service_host_with_port(): def test_prediction_service_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called def test_prediction_service_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that channel is used if provided. + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", channel=channel, + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_prediction_service_grpc_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.PredictionServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.PredictionServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, - ], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_prediction_service_transport_channel_mtls_with_client_cert_source( - transport_class, +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_prediction_service_grpc_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint ): - with mock.patch( - "grpc.ssl_channel_credentials", autospec=True - ) as grpc_ssl_channel_cred: - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.PredictionServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "transport_class", - [ - transports.PredictionServiceGrpcTransport, - transports.PredictionServiceGrpcAsyncIOTransport, - ], + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] ) -def test_prediction_service_transport_channel_mtls_with_adc(transport_class): +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - with mock.patch.object( - transport_class, "create_channel", autospec=True - ) as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + mock_cred = mock.Mock() + transport = transports.PredictionServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_prediction_service_grpc_lro_client(): From 2dd76513865a69b048c645b7466046b9ac2d92bd Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 06:00:23 -0700 Subject: [PATCH 15/25] Add Service Direcotry v1 protos and configs PiperOrigin-RevId: 333502684 Source-Author: Google APIs Source-Date: Thu Sep 24 06:33:53 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: d3697d47929f34c43bcc4de16c7c761a80e97cf1 Source-Link: https://github.com/googleapis/googleapis/commit/d3697d47929f34c43bcc4de16c7c761a80e97cf1 --- docs/automl_v1beta1/services.rst | 3 - .../services/auto_ml/async_client.py | 28 +- .../automl_v1/services/auto_ml/client.py | 92 +- .../services/auto_ml/transports/base.py | 2 +- .../services/auto_ml/transports/grpc.py | 46 +- .../auto_ml/transports/grpc_asyncio.py | 51 +- .../prediction_service/async_client.py | 23 +- .../services/prediction_service/client.py | 92 +- .../prediction_service/transports/base.py | 2 +- .../prediction_service/transports/grpc.py | 46 +- .../transports/grpc_asyncio.py | 51 +- google/cloud/automl_v1beta1/__init__.py | 8 +- .../proto/annotation_payload.proto | 77 ++ .../proto/annotation_spec.proto | 48 + .../automl_v1beta1/proto/classification.proto | 216 ++++ .../automl_v1beta1/proto/column_spec.proto | 78 ++ .../automl_v1beta1/proto/data_items.proto | 221 ++++ .../automl_v1beta1/proto/data_stats.proto | 166 +++ .../automl_v1beta1/proto/data_types.proto | 105 ++ .../cloud/automl_v1beta1/proto/dataset.proto | 96 ++ .../automl_v1beta1/proto/detection.proto | 135 ++ .../cloud/automl_v1beta1/proto/geometry.proto | 46 + google/cloud/automl_v1beta1/proto/image.proto | 193 +++ google/cloud/automl_v1beta1/proto/io.proto | 1132 +++++++++++++++++ google/cloud/automl_v1beta1/proto/model.proto | 108 ++ .../proto/model_evaluation.proto | 116 ++ .../automl_v1beta1/proto/operations.proto | 189 +++ .../proto/prediction_service.proto | 268 ++++ .../cloud/automl_v1beta1/proto/ranges.proto | 35 + .../automl_v1beta1/proto/regression.proto | 44 + .../cloud/automl_v1beta1/proto/service.proto | 800 ++++++++++++ .../automl_v1beta1/proto/table_spec.proto | 78 ++ .../cloud/automl_v1beta1/proto/tables.proto | 292 +++++ .../cloud/automl_v1beta1/proto/temporal.proto | 37 + google/cloud/automl_v1beta1/proto/text.proto | 65 + .../proto/text_extraction.proto | 68 + .../automl_v1beta1/proto/text_segment.proto | 41 + .../automl_v1beta1/proto/text_sentiment.proto | 80 ++ .../automl_v1beta1/proto/translation.proto | 69 + google/cloud/automl_v1beta1/proto/video.proto | 48 + .../services/auto_ml/async_client.py | 32 +- .../automl_v1beta1/services/auto_ml/client.py | 92 +- .../services/auto_ml/transports/base.py | 2 +- .../services/auto_ml/transports/grpc.py | 46 +- .../auto_ml/transports/grpc_asyncio.py | 51 +- .../prediction_service/async_client.py | 23 +- .../services/prediction_service/client.py | 92 +- .../prediction_service/transports/base.py | 2 +- .../prediction_service/transports/grpc.py | 46 +- .../transports/grpc_asyncio.py | 51 +- .../automl_v1beta1/types/classification.py | 4 +- .../cloud/automl_v1beta1/types/data_stats.py | 8 +- noxfile.py | 34 - synth.metadata | 224 +++- tests/unit/gapic/automl_v1/test_auto_ml.py | 545 ++++---- .../automl_v1/test_prediction_service.py | 496 ++++---- .../unit/gapic/automl_v1beta1/test_auto_ml.py | 603 ++++----- .../automl_v1beta1/test_prediction_service.py | 496 ++++---- 58 files changed, 6782 insertions(+), 1360 deletions(-) create mode 100644 google/cloud/automl_v1beta1/proto/annotation_payload.proto create mode 100644 google/cloud/automl_v1beta1/proto/annotation_spec.proto create mode 100644 google/cloud/automl_v1beta1/proto/classification.proto create mode 100644 google/cloud/automl_v1beta1/proto/column_spec.proto create mode 100644 google/cloud/automl_v1beta1/proto/data_items.proto create mode 100644 google/cloud/automl_v1beta1/proto/data_stats.proto create mode 100644 google/cloud/automl_v1beta1/proto/data_types.proto create mode 100644 google/cloud/automl_v1beta1/proto/dataset.proto create mode 100644 google/cloud/automl_v1beta1/proto/detection.proto create mode 100644 google/cloud/automl_v1beta1/proto/geometry.proto create mode 100644 google/cloud/automl_v1beta1/proto/image.proto create mode 100644 google/cloud/automl_v1beta1/proto/io.proto create mode 100644 google/cloud/automl_v1beta1/proto/model.proto create mode 100644 google/cloud/automl_v1beta1/proto/model_evaluation.proto create mode 100644 google/cloud/automl_v1beta1/proto/operations.proto create mode 100644 google/cloud/automl_v1beta1/proto/prediction_service.proto create mode 100644 google/cloud/automl_v1beta1/proto/ranges.proto create mode 100644 google/cloud/automl_v1beta1/proto/regression.proto create mode 100644 google/cloud/automl_v1beta1/proto/service.proto create mode 100644 google/cloud/automl_v1beta1/proto/table_spec.proto create mode 100644 google/cloud/automl_v1beta1/proto/tables.proto create mode 100644 google/cloud/automl_v1beta1/proto/temporal.proto create mode 100644 google/cloud/automl_v1beta1/proto/text.proto create mode 100644 google/cloud/automl_v1beta1/proto/text_extraction.proto create mode 100644 google/cloud/automl_v1beta1/proto/text_segment.proto create mode 100644 google/cloud/automl_v1beta1/proto/text_sentiment.proto create mode 100644 google/cloud/automl_v1beta1/proto/translation.proto create mode 100644 google/cloud/automl_v1beta1/proto/video.proto diff --git a/docs/automl_v1beta1/services.rst b/docs/automl_v1beta1/services.rst index 787e8566..9fa5c54f 100644 --- a/docs/automl_v1beta1/services.rst +++ b/docs/automl_v1beta1/services.rst @@ -7,6 +7,3 @@ Services for Google Cloud Automl v1beta1 API .. automodule:: google.cloud.automl_v1beta1.services.prediction_service :members: :inherited-members: -.. automodule:: google.cloud.automl_v1beta1.services.tables - :members: - :inherited-members: diff --git a/google/cloud/automl_v1/services/auto_ml/async_client.py b/google/cloud/automl_v1/services/auto_ml/async_client.py index 2b7f9c5c..23d7b118 100644 --- a/google/cloud/automl_v1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1/services/auto_ml/async_client.py @@ -28,8 +28,8 @@ from google.auth import credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1.services.auto_ml import pagers from google.cloud.automl_v1.types import annotation_spec from google.cloud.automl_v1.types import classification @@ -79,9 +79,10 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT - model_path = staticmethod(AutoMlClient.model_path) - dataset_path = staticmethod(AutoMlClient.dataset_path) + parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) + model_path = staticmethod(AutoMlClient.model_path) + parse_model_path = staticmethod(AutoMlClient.parse_model_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file @@ -112,16 +113,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1/services/auto_ml/client.py b/google/cloud/automl_v1/services/auto_ml/client.py index e615ce00..3765ac0b 100644 --- a/google/cloud/automl_v1/services/auto_ml/client.py +++ b/google/cloud/automl_v1/services/auto_ml/client.py @@ -16,22 +16,24 @@ # from collections import OrderedDict +from distutils import util import os import re -from typing import Callable, Dict, Sequence, Tuple, Type, Union +from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore +from google.api_core import client_options as client_options_lib # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1.services.auto_ml import pagers from google.cloud.automl_v1.types import annotation_spec from google.cloud.automl_v1.types import classification @@ -196,9 +198,9 @@ def parse_model_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: credentials.Credentials = None, - transport: Union[str, AutoMlTransport] = None, - client_options: ClientOptions = None, + credentials: Optional[credentials.Credentials] = None, + transport: Union[str, AutoMlTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the auto ml client. @@ -212,19 +214,22 @@ def __init__( transport (Union[str, ~.AutoMlTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. + client_options (client_options_lib.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -236,29 +241,47 @@ def __init__( creation failed for any reason. """ if isinstance(client_options, dict): - client_options = ClientOptions.from_dict(client_options) + client_options = client_options_lib.from_dict(client_options) if client_options is None: - client_options = ClientOptions.ClientOptions() + client_options = client_options_lib.ClientOptions() - if client_options.api_endpoint is None: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + ssl_credentials = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + import grpc # type: ignore + + cert, key = client_options.client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + is_mtls = True + else: + creds = SslCredentials() + is_mtls = creds.is_mtls + ssl_credentials = creds.ssl_credentials if is_mtls else None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") if use_mtls_env == "never": - client_options.api_endpoint = self.DEFAULT_ENDPOINT + api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - has_client_cert_source = ( - client_options.client_cert_source is not None - or mtls.has_default_client_cert_source() - ) - client_options.api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT - if has_client_cert_source - else self.DEFAULT_ENDPOINT + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -282,10 +305,9 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=client_options.api_endpoint, + host=api_endpoint, scopes=client_options.scopes, - api_mtls_endpoint=client_options.api_endpoint, - client_cert_source=client_options.client_cert_source, + ssl_channel_credentials=ssl_credentials, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1/services/auto_ml/transports/base.py b/google/cloud/automl_v1/services/auto_ml/transports/base.py index 5e230105..b1e12781 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth +from google import auth # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py index 100f50f6..b957e5cd 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py @@ -15,6 +15,7 @@ # limitations under the License. # +import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -24,7 +25,6 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore - import grpc # type: ignore from google.cloud.automl_v1.types import annotation_spec @@ -78,6 +78,7 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -98,14 +99,16 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -128,6 +131,11 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -158,6 +166,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) self._stubs = {} # type: Dict[str, Callable] @@ -223,13 +248,6 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py b/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py index 39e15a79..0778c063 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py @@ -15,11 +15,13 @@ # limitations under the License. # +import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore +from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -120,6 +122,7 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -141,14 +144,16 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -171,12 +176,22 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -196,6 +211,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) # Run the base constructor. super().__init__( @@ -216,13 +248,6 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/prediction_service/async_client.py b/google/cloud/automl_v1/services/prediction_service/async_client.py index df141602..d77836a0 100644 --- a/google/cloud/automl_v1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1/services/prediction_service/async_client.py @@ -28,8 +28,8 @@ from google.auth import credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1.types import annotation_payload from google.cloud.automl_v1.types import data_items from google.cloud.automl_v1.types import io @@ -82,16 +82,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1/services/prediction_service/client.py b/google/cloud/automl_v1/services/prediction_service/client.py index 2ccfd9fc..d2c1971a 100644 --- a/google/cloud/automl_v1/services/prediction_service/client.py +++ b/google/cloud/automl_v1/services/prediction_service/client.py @@ -16,22 +16,24 @@ # from collections import OrderedDict +from distutils import util import os import re -from typing import Callable, Dict, Sequence, Tuple, Type, Union +from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore +from google.api_core import client_options as client_options_lib # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1.types import annotation_payload from google.cloud.automl_v1.types import data_items from google.cloud.automl_v1.types import io @@ -142,9 +144,9 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): def __init__( self, *, - credentials: credentials.Credentials = None, - transport: Union[str, PredictionServiceTransport] = None, - client_options: ClientOptions = None, + credentials: Optional[credentials.Credentials] = None, + transport: Union[str, PredictionServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the prediction service client. @@ -158,19 +160,22 @@ def __init__( transport (Union[str, ~.PredictionServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. + client_options (client_options_lib.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -182,29 +187,47 @@ def __init__( creation failed for any reason. """ if isinstance(client_options, dict): - client_options = ClientOptions.from_dict(client_options) + client_options = client_options_lib.from_dict(client_options) if client_options is None: - client_options = ClientOptions.ClientOptions() + client_options = client_options_lib.ClientOptions() - if client_options.api_endpoint is None: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + ssl_credentials = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + import grpc # type: ignore + + cert, key = client_options.client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + is_mtls = True + else: + creds = SslCredentials() + is_mtls = creds.is_mtls + ssl_credentials = creds.ssl_credentials if is_mtls else None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") if use_mtls_env == "never": - client_options.api_endpoint = self.DEFAULT_ENDPOINT + api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - has_client_cert_source = ( - client_options.client_cert_source is not None - or mtls.has_default_client_cert_source() - ) - client_options.api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT - if has_client_cert_source - else self.DEFAULT_ENDPOINT + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -228,10 +251,9 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=client_options.api_endpoint, + host=api_endpoint, scopes=client_options.scopes, - api_mtls_endpoint=client_options.api_endpoint, - client_cert_source=client_options.client_cert_source, + ssl_channel_credentials=ssl_credentials, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1/services/prediction_service/transports/base.py b/google/cloud/automl_v1/services/prediction_service/transports/base.py index 349d8793..f019a8dc 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/base.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth +from google import auth # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py index e4508add..9a2c8e9b 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py @@ -15,6 +15,7 @@ # limitations under the License. # +import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -24,7 +25,6 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore - import grpc # type: ignore from google.cloud.automl_v1.types import prediction_service @@ -61,6 +61,7 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -81,14 +82,16 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -111,6 +114,11 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -141,6 +149,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) self._stubs = {} # type: Dict[str, Callable] @@ -206,13 +231,6 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py b/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py index f92ad264..eddcb6ab 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py @@ -15,11 +15,13 @@ # limitations under the License. # +import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore +from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -103,6 +105,7 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -124,14 +127,16 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -154,12 +159,22 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -179,6 +194,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) # Run the base constructor. super().__init__( @@ -199,13 +231,6 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 904a45aa..44f619cb 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -17,8 +17,8 @@ from .services.auto_ml import AutoMlClient from .services.prediction_service import PredictionServiceClient -from .services.tables.gcs_client import GcsClient -from .services.tables.tables_client import TablesClient +from .tables.gcs_client import GcsClient +from .tables.tables_client import TablesClient from .types.annotation_payload import AnnotationPayload from .types.annotation_spec import AnnotationSpec from .types.classification import ClassificationAnnotation @@ -149,6 +149,7 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", + "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -227,7 +228,6 @@ "OutputConfig", "PredictRequest", "PredictResponse", - "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "AutoMlClient", + "PredictionServiceClient", ) diff --git a/google/cloud/automl_v1beta1/proto/annotation_payload.proto b/google/cloud/automl_v1beta1/proto/annotation_payload.proto new file mode 100644 index 00000000..f62bb269 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/annotation_payload.proto @@ -0,0 +1,77 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/cloud/automl/v1beta1/detection.proto"; +import "google/cloud/automl/v1beta1/tables.proto"; +import "google/cloud/automl/v1beta1/text_extraction.proto"; +import "google/cloud/automl/v1beta1/text_sentiment.proto"; +import "google/cloud/automl/v1beta1/translation.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Contains annotation information that is relevant to AutoML. +message AnnotationPayload { + // Output only . Additional information about the annotation + // specific to the AutoML domain. + oneof detail { + // Annotation details for translation. + TranslationAnnotation translation = 2; + + // Annotation details for content or image classification. + ClassificationAnnotation classification = 3; + + // Annotation details for image object detection. + ImageObjectDetectionAnnotation image_object_detection = 4; + + // Annotation details for video classification. + // Returned for Video Classification predictions. + VideoClassificationAnnotation video_classification = 9; + + // Annotation details for video object tracking. + VideoObjectTrackingAnnotation video_object_tracking = 8; + + // Annotation details for text extraction. + TextExtractionAnnotation text_extraction = 6; + + // Annotation details for text sentiment. + TextSentimentAnnotation text_sentiment = 7; + + // Annotation details for Tables. + TablesAnnotation tables = 10; + } + + // Output only . The resource ID of the annotation spec that + // this annotation pertains to. The annotation spec comes from either an + // ancestor dataset, or the dataset that was used to train the model in use. + string annotation_spec_id = 1; + + // Output only. The value of + // [display_name][google.cloud.automl.v1beta1.AnnotationSpec.display_name] + // when the model was trained. Because this field returns a value at model + // training time, for different models trained using the same dataset, the + // returned value could be different as model owner could update the + // `display_name` between any two model training. + string display_name = 5; +} diff --git a/google/cloud/automl_v1beta1/proto/annotation_spec.proto b/google/cloud/automl_v1beta1/proto/annotation_spec.proto new file mode 100644 index 00000000..d9df07ee --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/annotation_spec.proto @@ -0,0 +1,48 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A definition of an annotation spec. +message AnnotationSpec { + option (google.api.resource) = { + type: "automl.googleapis.com/AnnotationSpec" + pattern: "projects/{project}/locations/{location}/datasets/{dataset}/annotationSpecs/{annotation_spec}" + }; + + // Output only. Resource name of the annotation spec. + // Form: + // + // 'projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/annotationSpecs/{annotation_spec_id}' + string name = 1; + + // Required. The name of the annotation spec to show in the interface. The name can be + // up to 32 characters long and must match the regexp `[a-zA-Z0-9_]+`. + string display_name = 2; + + // Output only. The number of examples in the parent dataset + // labeled by the annotation spec. + int32 example_count = 9; +} diff --git a/google/cloud/automl_v1beta1/proto/classification.proto b/google/cloud/automl_v1beta1/proto/classification.proto new file mode 100644 index 00000000..0594d01e --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/classification.proto @@ -0,0 +1,216 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/temporal.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_outer_classname = "ClassificationProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Type of the classification problem. +enum ClassificationType { + // An un-set value of this enum. + CLASSIFICATION_TYPE_UNSPECIFIED = 0; + + // At most one label is allowed per example. + MULTICLASS = 1; + + // Multiple labels are allowed for one example. + MULTILABEL = 2; +} + +// Contains annotation details specific to classification. +message ClassificationAnnotation { + // Output only. A confidence estimate between 0.0 and 1.0. A higher value + // means greater confidence that the annotation is positive. If a user + // approves an annotation as negative or positive, the score value remains + // unchanged. If a user creates an annotation, the score is 0 for negative or + // 1 for positive. + float score = 1; +} + +// Contains annotation details specific to video classification. +message VideoClassificationAnnotation { + // Output only. Expresses the type of video classification. Possible values: + // + // * `segment` - Classification done on a specified by user + // time segment of a video. AnnotationSpec is answered to be present + // in that time segment, if it is present in any part of it. The video + // ML model evaluations are done only for this type of classification. + // + // * `shot`- Shot-level classification. + // AutoML Video Intelligence determines the boundaries + // for each camera shot in the entire segment of the video that user + // specified in the request configuration. AutoML Video Intelligence + // then returns labels and their confidence scores for each detected + // shot, along with the start and end time of the shot. + // WARNING: Model evaluation is not done for this classification type, + // the quality of it depends on training data, but there are no + // metrics provided to describe that quality. + // + // * `1s_interval` - AutoML Video Intelligence returns labels and their + // confidence scores for each second of the entire segment of the video + // that user specified in the request configuration. + // WARNING: Model evaluation is not done for this classification type, + // the quality of it depends on training data, but there are no + // metrics provided to describe that quality. + string type = 1; + + // Output only . The classification details of this annotation. + ClassificationAnnotation classification_annotation = 2; + + // Output only . The time segment of the video to which the + // annotation applies. + TimeSegment time_segment = 3; +} + +// Model evaluation metrics for classification problems. +// Note: For Video Classification this metrics only describe quality of the +// Video Classification predictions of "segment_classification" type. +message ClassificationEvaluationMetrics { + // Metrics for a single confidence threshold. + message ConfidenceMetricsEntry { + // Output only. Metrics are computed with an assumption that the model + // never returns predictions with score lower than this value. + float confidence_threshold = 1; + + // Output only. Metrics are computed with an assumption that the model + // always returns at most this many predictions (ordered by their score, + // descendingly), but they all still need to meet the confidence_threshold. + int32 position_threshold = 14; + + // Output only. Recall (True Positive Rate) for the given confidence + // threshold. + float recall = 2; + + // Output only. Precision for the given confidence threshold. + float precision = 3; + + // Output only. False Positive Rate for the given confidence threshold. + float false_positive_rate = 8; + + // Output only. The harmonic mean of recall and precision. + float f1_score = 4; + + // Output only. The Recall (True Positive Rate) when only considering the + // label that has the highest prediction score and not below the confidence + // threshold for each example. + float recall_at1 = 5; + + // Output only. The precision when only considering the label that has the + // highest prediction score and not below the confidence threshold for each + // example. + float precision_at1 = 6; + + // Output only. The False Positive Rate when only considering the label that + // has the highest prediction score and not below the confidence threshold + // for each example. + float false_positive_rate_at1 = 9; + + // Output only. The harmonic mean of [recall_at1][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfidenceMetricsEntry.recall_at1] and [precision_at1][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfidenceMetricsEntry.precision_at1]. + float f1_score_at1 = 7; + + // Output only. The number of model created labels that match a ground truth + // label. + int64 true_positive_count = 10; + + // Output only. The number of model created labels that do not match a + // ground truth label. + int64 false_positive_count = 11; + + // Output only. The number of ground truth labels that are not matched + // by a model created label. + int64 false_negative_count = 12; + + // Output only. The number of labels that were not created by the model, + // but if they would, they would not match a ground truth label. + int64 true_negative_count = 13; + } + + // Confusion matrix of the model running the classification. + message ConfusionMatrix { + // Output only. A row in the confusion matrix. + message Row { + // Output only. Value of the specific cell in the confusion matrix. + // The number of values each row has (i.e. the length of the row) is equal + // to the length of the `annotation_spec_id` field or, if that one is not + // populated, length of the [display_name][google.cloud.automl.v1beta1.ClassificationEvaluationMetrics.ConfusionMatrix.display_name] field. + repeated int32 example_count = 1; + } + + // Output only. IDs of the annotation specs used in the confusion matrix. + // For Tables CLASSIFICATION + // + // [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] + // only list of [annotation_spec_display_name-s][] is populated. + repeated string annotation_spec_id = 1; + + // Output only. Display name of the annotation specs used in the confusion + // matrix, as they were at the moment of the evaluation. For Tables + // CLASSIFICATION + // + // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type], + // distinct values of the target column at the moment of the model + // evaluation are populated here. + repeated string display_name = 3; + + // Output only. Rows in the confusion matrix. The number of rows is equal to + // the size of `annotation_spec_id`. + // `row[i].example_count[j]` is the number of examples that have ground + // truth of the `annotation_spec_id[i]` and are predicted as + // `annotation_spec_id[j]` by the model being evaluated. + repeated Row row = 2; + } + + // Output only. The Area Under Precision-Recall Curve metric. Micro-averaged + // for the overall evaluation. + float au_prc = 1; + + // Output only. The Area Under Precision-Recall Curve metric based on priors. + // Micro-averaged for the overall evaluation. + // Deprecated. + float base_au_prc = 2 [deprecated = true]; + + // Output only. The Area Under Receiver Operating Characteristic curve metric. + // Micro-averaged for the overall evaluation. + float au_roc = 6; + + // Output only. The Log Loss metric. + float log_loss = 7; + + // Output only. Metrics for each confidence_threshold in + // 0.00,0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 and + // position_threshold = INT32_MAX_VALUE. + // ROC and precision-recall curves, and other aggregated metrics are derived + // from them. The confidence metrics entries may also be supplied for + // additional values of position_threshold, but from these no aggregated + // metrics are computed. + repeated ConfidenceMetricsEntry confidence_metrics_entry = 3; + + // Output only. Confusion matrix of the evaluation. + // Only set for MULTICLASS classification problems where number + // of labels is no more than 10. + // Only set for model level evaluation, not for evaluation per label. + ConfusionMatrix confusion_matrix = 4; + + // Output only. The annotation spec ids used for this evaluation. + repeated string annotation_spec_id = 5; +} diff --git a/google/cloud/automl_v1beta1/proto/column_spec.proto b/google/cloud/automl_v1beta1/proto/column_spec.proto new file mode 100644 index 00000000..03389b8a --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/column_spec.proto @@ -0,0 +1,78 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/data_stats.proto"; +import "google/cloud/automl/v1beta1/data_types.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A representation of a column in a relational table. When listing them, column specs are returned in the same order in which they were +// given on import . +// Used by: +// * Tables +message ColumnSpec { + option (google.api.resource) = { + type: "automl.googleapis.com/ColumnSpec" + pattern: "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}" + }; + + // Identifies the table's column, and its correlation with the column this + // ColumnSpec describes. + message CorrelatedColumn { + // The column_spec_id of the correlated column, which belongs to the same + // table as the in-context column. + string column_spec_id = 1; + + // Correlation between this and the in-context column. + CorrelationStats correlation_stats = 2; + } + + // Output only. The resource name of the column specs. + // Form: + // + // `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/tableSpecs/{table_spec_id}/columnSpecs/{column_spec_id}` + string name = 1; + + // The data type of elements stored in the column. + DataType data_type = 2; + + // Output only. The name of the column to show in the interface. The name can + // be up to 100 characters long and can consist only of ASCII Latin letters + // A-Z and a-z, ASCII digits 0-9, underscores(_), and forward slashes(/), and + // must start with a letter or a digit. + string display_name = 3; + + // Output only. Stats of the series of values in the column. + // This field may be stale, see the ancestor's + // Dataset.tables_dataset_metadata.stats_update_time field + // for the timestamp at which these stats were last updated. + DataStats data_stats = 4; + + // Deprecated. + repeated CorrelatedColumn top_correlated_columns = 5; + + // Used to perform consistent read-modify-write updates. If not set, a blind + // "overwrite" update happens. + string etag = 6; +} diff --git a/google/cloud/automl_v1beta1/proto/data_items.proto b/google/cloud/automl_v1beta1/proto/data_items.proto new file mode 100644 index 00000000..9b9187ad --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/data_items.proto @@ -0,0 +1,221 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/geometry.proto"; +import "google/cloud/automl/v1beta1/io.proto"; +import "google/cloud/automl/v1beta1/temporal.proto"; +import "google/cloud/automl/v1beta1/text_segment.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/struct.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A representation of an image. +// Only images up to 30MB in size are supported. +message Image { + // Input only. The data representing the image. + // For Predict calls [image_bytes][google.cloud.automl.v1beta1.Image.image_bytes] must be set, as other options are not + // currently supported by prediction API. You can read the contents of an + // uploaded image by using the [content_uri][google.cloud.automl.v1beta1.Image.content_uri] field. + oneof data { + // Image content represented as a stream of bytes. + // Note: As with all `bytes` fields, protobuffers use a pure binary + // representation, whereas JSON representations use base64. + bytes image_bytes = 1; + + // An input config specifying the content of the image. + InputConfig input_config = 6; + } + + // Output only. HTTP URI to the thumbnail image. + string thumbnail_uri = 4; +} + +// A representation of a text snippet. +message TextSnippet { + // Required. The content of the text snippet as a string. Up to 250000 + // characters long. + string content = 1; + + // Optional. The format of [content][google.cloud.automl.v1beta1.TextSnippet.content]. Currently the only two allowed + // values are "text/html" and "text/plain". If left blank, the format is + // automatically determined from the type of the uploaded [content][google.cloud.automl.v1beta1.TextSnippet.content]. + string mime_type = 2; + + // Output only. HTTP URI where you can download the content. + string content_uri = 4; +} + +// Message that describes dimension of a document. +message DocumentDimensions { + // Unit of the document dimension. + enum DocumentDimensionUnit { + // Should not be used. + DOCUMENT_DIMENSION_UNIT_UNSPECIFIED = 0; + + // Document dimension is measured in inches. + INCH = 1; + + // Document dimension is measured in centimeters. + CENTIMETER = 2; + + // Document dimension is measured in points. 72 points = 1 inch. + POINT = 3; + } + + // Unit of the dimension. + DocumentDimensionUnit unit = 1; + + // Width value of the document, works together with the unit. + float width = 2; + + // Height value of the document, works together with the unit. + float height = 3; +} + +// A structured text document e.g. a PDF. +message Document { + // Describes the layout information of a [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the document. + message Layout { + // The type of TextSegment in the context of the original document. + enum TextSegmentType { + // Should not be used. + TEXT_SEGMENT_TYPE_UNSPECIFIED = 0; + + // The text segment is a token. e.g. word. + TOKEN = 1; + + // The text segment is a paragraph. + PARAGRAPH = 2; + + // The text segment is a form field. + FORM_FIELD = 3; + + // The text segment is the name part of a form field. It will be treated + // as child of another FORM_FIELD TextSegment if its span is subspan of + // another TextSegment with type FORM_FIELD. + FORM_FIELD_NAME = 4; + + // The text segment is the text content part of a form field. It will be + // treated as child of another FORM_FIELD TextSegment if its span is + // subspan of another TextSegment with type FORM_FIELD. + FORM_FIELD_CONTENTS = 5; + + // The text segment is a whole table, including headers, and all rows. + TABLE = 6; + + // The text segment is a table's headers. It will be treated as child of + // another TABLE TextSegment if its span is subspan of another TextSegment + // with type TABLE. + TABLE_HEADER = 7; + + // The text segment is a row in table. It will be treated as child of + // another TABLE TextSegment if its span is subspan of another TextSegment + // with type TABLE. + TABLE_ROW = 8; + + // The text segment is a cell in table. It will be treated as child of + // another TABLE_ROW TextSegment if its span is subspan of another + // TextSegment with type TABLE_ROW. + TABLE_CELL = 9; + } + + // Text Segment that represents a segment in + // [document_text][google.cloud.automl.v1beta1.Document.document_text]. + TextSegment text_segment = 1; + + // Page number of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the original document, starts + // from 1. + int32 page_number = 2; + + // The position of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in the page. + // Contains exactly 4 + // + // [normalized_vertices][google.cloud.automl.v1beta1.BoundingPoly.normalized_vertices] + // and they are connected by edges in the order provided, which will + // represent a rectangle parallel to the frame. The + // [NormalizedVertex-s][google.cloud.automl.v1beta1.NormalizedVertex] are + // relative to the page. + // Coordinates are based on top-left as point (0,0). + BoundingPoly bounding_poly = 3; + + // The type of the [text_segment][google.cloud.automl.v1beta1.Document.Layout.text_segment] in document. + TextSegmentType text_segment_type = 4; + } + + // An input config specifying the content of the document. + DocumentInputConfig input_config = 1; + + // The plain text version of this document. + TextSnippet document_text = 2; + + // Describes the layout of the document. + // Sorted by [page_number][]. + repeated Layout layout = 3; + + // The dimensions of the page in the document. + DocumentDimensions document_dimensions = 4; + + // Number of pages in the document. + int32 page_count = 5; +} + +// A representation of a row in a relational table. +message Row { + // The resource IDs of the column specs describing the columns of the row. + // If set must contain, but possibly in a different order, all input + // feature + // + // [column_spec_ids][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] + // of the Model this row is being passed to. + // Note: The below `values` field must match order of this field, if this + // field is set. + repeated string column_spec_ids = 2; + + // Required. The values of the row cells, given in the same order as the + // column_spec_ids, or, if not set, then in the same order as input + // feature + // + // [column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] + // of the Model this row is being passed to. + repeated google.protobuf.Value values = 3; +} + +// Example data used for training or prediction. +message ExamplePayload { + // Required. Input only. The example data. + oneof payload { + // Example image. + Image image = 1; + + // Example text. + TextSnippet text_snippet = 2; + + // Example document. + Document document = 4; + + // Example relational table row. + Row row = 3; + } +} diff --git a/google/cloud/automl_v1beta1/proto/data_stats.proto b/google/cloud/automl_v1beta1/proto/data_stats.proto new file mode 100644 index 00000000..c13a5d45 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/data_stats.proto @@ -0,0 +1,166 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// The data statistics of a series of values that share the same DataType. +message DataStats { + // The data statistics specific to a DataType. + oneof stats { + // The statistics for FLOAT64 DataType. + Float64Stats float64_stats = 3; + + // The statistics for STRING DataType. + StringStats string_stats = 4; + + // The statistics for TIMESTAMP DataType. + TimestampStats timestamp_stats = 5; + + // The statistics for ARRAY DataType. + ArrayStats array_stats = 6; + + // The statistics for STRUCT DataType. + StructStats struct_stats = 7; + + // The statistics for CATEGORY DataType. + CategoryStats category_stats = 8; + } + + // The number of distinct values. + int64 distinct_value_count = 1; + + // The number of values that are null. + int64 null_value_count = 2; + + // The number of values that are valid. + int64 valid_value_count = 9; +} + +// The data statistics of a series of FLOAT64 values. +message Float64Stats { + // A bucket of a histogram. + message HistogramBucket { + // The minimum value of the bucket, inclusive. + double min = 1; + + // The maximum value of the bucket, exclusive unless max = `"Infinity"`, in + // which case it's inclusive. + double max = 2; + + // The number of data values that are in the bucket, i.e. are between + // min and max values. + int64 count = 3; + } + + // The mean of the series. + double mean = 1; + + // The standard deviation of the series. + double standard_deviation = 2; + + // Ordered from 0 to k k-quantile values of the data series of n values. + // The value at index i is, approximately, the i*n/k-th smallest value in the + // series; for i = 0 and i = k these are, respectively, the min and max + // values. + repeated double quantiles = 3; + + // Histogram buckets of the data series. Sorted by the min value of the + // bucket, ascendingly, and the number of the buckets is dynamically + // generated. The buckets are non-overlapping and completely cover whole + // FLOAT64 range with min of first bucket being `"-Infinity"`, and max of + // the last one being `"Infinity"`. + repeated HistogramBucket histogram_buckets = 4; +} + +// The data statistics of a series of STRING values. +message StringStats { + // The statistics of a unigram. + message UnigramStats { + // The unigram. + string value = 1; + + // The number of occurrences of this unigram in the series. + int64 count = 2; + } + + // The statistics of the top 20 unigrams, ordered by + // [count][google.cloud.automl.v1beta1.StringStats.UnigramStats.count]. + repeated UnigramStats top_unigram_stats = 1; +} + +// The data statistics of a series of TIMESTAMP values. +message TimestampStats { + // Stats split by a defined in context granularity. + message GranularStats { + // A map from granularity key to example count for that key. + // E.g. for hour_of_day `13` means 1pm, or for month_of_year `5` means May). + map buckets = 1; + } + + // The string key is the pre-defined granularity. Currently supported: + // hour_of_day, day_of_week, month_of_year. + // Granularities finer that the granularity of timestamp data are not + // populated (e.g. if timestamps are at day granularity, then hour_of_day + // is not populated). + map granular_stats = 1; +} + +// The data statistics of a series of ARRAY values. +message ArrayStats { + // Stats of all the values of all arrays, as if they were a single long + // series of data. The type depends on the element type of the array. + DataStats member_stats = 2; +} + +// The data statistics of a series of STRUCT values. +message StructStats { + // Map from a field name of the struct to data stats aggregated over series + // of all data in that field across all the structs. + map field_stats = 1; +} + +// The data statistics of a series of CATEGORY values. +message CategoryStats { + // The statistics of a single CATEGORY value. + message SingleCategoryStats { + // The CATEGORY value. + string value = 1; + + // The number of occurrences of this value in the series. + int64 count = 2; + } + + // The statistics of the top 20 CATEGORY values, ordered by + // + // [count][google.cloud.automl.v1beta1.CategoryStats.SingleCategoryStats.count]. + repeated SingleCategoryStats top_category_stats = 1; +} + +// A correlation statistics between two series of DataType values. The series +// may have differing DataType-s, but within a single series the DataType must +// be the same. +message CorrelationStats { + // The correlation value using the Cramer's V measure. + double cramers_v = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/data_types.proto b/google/cloud/automl_v1beta1/proto/data_types.proto new file mode 100644 index 00000000..6f77f56b --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/data_types.proto @@ -0,0 +1,105 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// `TypeCode` is used as a part of +// [DataType][google.cloud.automl.v1beta1.DataType]. +enum TypeCode { + // Not specified. Should not be used. + TYPE_CODE_UNSPECIFIED = 0; + + // Encoded as `number`, or the strings `"NaN"`, `"Infinity"`, or + // `"-Infinity"`. + FLOAT64 = 3; + + // Must be between 0AD and 9999AD. Encoded as `string` according to + // [time_format][google.cloud.automl.v1beta1.DataType.time_format], or, if + // that format is not set, then in RFC 3339 `date-time` format, where + // `time-offset` = `"Z"` (e.g. 1985-04-12T23:20:50.52Z). + TIMESTAMP = 4; + + // Encoded as `string`. + STRING = 6; + + // Encoded as `list`, where the list elements are represented according to + // + // [list_element_type][google.cloud.automl.v1beta1.DataType.list_element_type]. + ARRAY = 8; + + // Encoded as `struct`, where field values are represented according to + // [struct_type][google.cloud.automl.v1beta1.DataType.struct_type]. + STRUCT = 9; + + // Values of this type are not further understood by AutoML, + // e.g. AutoML is unable to tell the order of values (as it could with + // FLOAT64), or is unable to say if one value contains another (as it + // could with STRING). + // Encoded as `string` (bytes should be base64-encoded, as described in RFC + // 4648, section 4). + CATEGORY = 10; +} + +// Indicated the type of data that can be stored in a structured data entity +// (e.g. a table). +message DataType { + // Details of DataType-s that need additional specification. + oneof details { + // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [ARRAY][google.cloud.automl.v1beta1.TypeCode.ARRAY], + // then `list_element_type` is the type of the elements. + DataType list_element_type = 2; + + // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [STRUCT][google.cloud.automl.v1beta1.TypeCode.STRUCT], then `struct_type` + // provides type information for the struct's fields. + StructType struct_type = 3; + + // If [type_code][google.cloud.automl.v1beta1.DataType.type_code] == [TIMESTAMP][google.cloud.automl.v1beta1.TypeCode.TIMESTAMP] + // then `time_format` provides the format in which that time field is + // expressed. The time_format must either be one of: + // * `UNIX_SECONDS` + // * `UNIX_MILLISECONDS` + // * `UNIX_MICROSECONDS` + // * `UNIX_NANOSECONDS` + // (for respectively number of seconds, milliseconds, microseconds and + // nanoseconds since start of the Unix epoch); + // or be written in `strftime` syntax. If time_format is not set, then the + // default format as described on the type_code is used. + string time_format = 5; + } + + // Required. The [TypeCode][google.cloud.automl.v1beta1.TypeCode] for this type. + TypeCode type_code = 1; + + // If true, this DataType can also be `NULL`. In .CSV files `NULL` value is + // expressed as an empty string. + bool nullable = 4; +} + +// `StructType` defines the DataType-s of a [STRUCT][google.cloud.automl.v1beta1.TypeCode.STRUCT] type. +message StructType { + // Unordered map of struct field names to their data types. + // Fields cannot be added or removed via Update. Their names and + // data types are still mutable. + map fields = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/dataset.proto b/google/cloud/automl_v1beta1/proto/dataset.proto new file mode 100644 index 00000000..8d1b8d93 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/dataset.proto @@ -0,0 +1,96 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/image.proto"; +import "google/cloud/automl/v1beta1/tables.proto"; +import "google/cloud/automl/v1beta1/text.proto"; +import "google/cloud/automl/v1beta1/translation.proto"; +import "google/cloud/automl/v1beta1/video.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A workspace for solving a single, particular machine learning (ML) problem. +// A workspace contains examples that may be annotated. +message Dataset { + option (google.api.resource) = { + type: "automl.googleapis.com/Dataset" + pattern: "projects/{project}/locations/{location}/datasets/{dataset}" + }; + + // Required. + // The dataset metadata that is specific to the problem type. + oneof dataset_metadata { + // Metadata for a dataset used for translation. + TranslationDatasetMetadata translation_dataset_metadata = 23; + + // Metadata for a dataset used for image classification. + ImageClassificationDatasetMetadata image_classification_dataset_metadata = 24; + + // Metadata for a dataset used for text classification. + TextClassificationDatasetMetadata text_classification_dataset_metadata = 25; + + // Metadata for a dataset used for image object detection. + ImageObjectDetectionDatasetMetadata image_object_detection_dataset_metadata = 26; + + // Metadata for a dataset used for video classification. + VideoClassificationDatasetMetadata video_classification_dataset_metadata = 31; + + // Metadata for a dataset used for video object tracking. + VideoObjectTrackingDatasetMetadata video_object_tracking_dataset_metadata = 29; + + // Metadata for a dataset used for text extraction. + TextExtractionDatasetMetadata text_extraction_dataset_metadata = 28; + + // Metadata for a dataset used for text sentiment. + TextSentimentDatasetMetadata text_sentiment_dataset_metadata = 30; + + // Metadata for a dataset used for Tables. + TablesDatasetMetadata tables_dataset_metadata = 33; + } + + // Output only. The resource name of the dataset. + // Form: `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}` + string name = 1; + + // Required. The name of the dataset to show in the interface. The name can be + // up to 32 characters long and can consist only of ASCII Latin letters A-Z + // and a-z, underscores + // (_), and ASCII digits 0-9. + string display_name = 2; + + // User-provided description of the dataset. The description can be up to + // 25000 characters long. + string description = 3; + + // Output only. The number of examples in the dataset. + int32 example_count = 21; + + // Output only. Timestamp when this dataset was created. + google.protobuf.Timestamp create_time = 14; + + // Used to perform consistent read-modify-write updates. If not set, a blind + // "overwrite" update happens. + string etag = 17; +} diff --git a/google/cloud/automl_v1beta1/proto/detection.proto b/google/cloud/automl_v1beta1/proto/detection.proto new file mode 100644 index 00000000..c5864e20 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/detection.proto @@ -0,0 +1,135 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/geometry.proto"; +import "google/protobuf/duration.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Annotation details for image object detection. +message ImageObjectDetectionAnnotation { + // Output only. The rectangle representing the object location. + BoundingPoly bounding_box = 1; + + // Output only. The confidence that this annotation is positive for the parent example, + // value in [0, 1], higher means higher positivity confidence. + float score = 2; +} + +// Annotation details for video object tracking. +message VideoObjectTrackingAnnotation { + // Optional. The instance of the object, expressed as a positive integer. Used to tell + // apart objects of the same type (i.e. AnnotationSpec) when multiple are + // present on a single example. + // NOTE: Instance ID prediction quality is not a part of model evaluation and + // is done as best effort. Especially in cases when an entity goes + // off-screen for a longer time (minutes), when it comes back it may be given + // a new instance ID. + string instance_id = 1; + + // Required. A time (frame) of a video to which this annotation pertains. + // Represented as the duration since the video's start. + google.protobuf.Duration time_offset = 2; + + // Required. The rectangle representing the object location on the frame (i.e. + // at the time_offset of the video). + BoundingPoly bounding_box = 3; + + // Output only. The confidence that this annotation is positive for the video at + // the time_offset, value in [0, 1], higher means higher positivity + // confidence. For annotations created by the user the score is 1. When + // user approves an annotation, the original float score is kept (and not + // changed to 1). + float score = 4; +} + +// Bounding box matching model metrics for a single intersection-over-union +// threshold and multiple label match confidence thresholds. +message BoundingBoxMetricsEntry { + // Metrics for a single confidence threshold. + message ConfidenceMetricsEntry { + // Output only. The confidence threshold value used to compute the metrics. + float confidence_threshold = 1; + + // Output only. Recall under the given confidence threshold. + float recall = 2; + + // Output only. Precision under the given confidence threshold. + float precision = 3; + + // Output only. The harmonic mean of recall and precision. + float f1_score = 4; + } + + // Output only. The intersection-over-union threshold value used to compute + // this metrics entry. + float iou_threshold = 1; + + // Output only. The mean average precision, most often close to au_prc. + float mean_average_precision = 2; + + // Output only. Metrics for each label-match confidence_threshold from + // 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99. Precision-recall curve is + // derived from them. + repeated ConfidenceMetricsEntry confidence_metrics_entries = 3; +} + +// Model evaluation metrics for image object detection problems. +// Evaluates prediction quality of labeled bounding boxes. +message ImageObjectDetectionEvaluationMetrics { + // Output only. The total number of bounding boxes (i.e. summed over all + // images) the ground truth used to create this evaluation had. + int32 evaluated_bounding_box_count = 1; + + // Output only. The bounding boxes match metrics for each + // Intersection-over-union threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 + // and each label confidence threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 + // pair. + repeated BoundingBoxMetricsEntry bounding_box_metrics_entries = 2; + + // Output only. The single metric for bounding boxes evaluation: + // the mean_average_precision averaged over all bounding_box_metrics_entries. + float bounding_box_mean_average_precision = 3; +} + +// Model evaluation metrics for video object tracking problems. +// Evaluates prediction quality of both labeled bounding boxes and labeled +// tracks (i.e. series of bounding boxes sharing same label and instance ID). +message VideoObjectTrackingEvaluationMetrics { + // Output only. The number of video frames used to create this evaluation. + int32 evaluated_frame_count = 1; + + // Output only. The total number of bounding boxes (i.e. summed over all + // frames) the ground truth used to create this evaluation had. + int32 evaluated_bounding_box_count = 2; + + // Output only. The bounding boxes match metrics for each + // Intersection-over-union threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 + // and each label confidence threshold 0.05,0.10,...,0.95,0.96,0.97,0.98,0.99 + // pair. + repeated BoundingBoxMetricsEntry bounding_box_metrics_entries = 4; + + // Output only. The single metric for bounding boxes evaluation: + // the mean_average_precision averaged over all bounding_box_metrics_entries. + float bounding_box_mean_average_precision = 6; +} diff --git a/google/cloud/automl_v1beta1/proto/geometry.proto b/google/cloud/automl_v1beta1/proto/geometry.proto new file mode 100644 index 00000000..d5654aac --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/geometry.proto @@ -0,0 +1,46 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A vertex represents a 2D point in the image. +// The normalized vertex coordinates are between 0 to 1 fractions relative to +// the original plane (image, video). E.g. if the plane (e.g. whole image) would +// have size 10 x 20 then a point with normalized coordinates (0.1, 0.3) would +// be at the position (1, 6) on that plane. +message NormalizedVertex { + // Required. Horizontal coordinate. + float x = 1; + + // Required. Vertical coordinate. + float y = 2; +} + +// A bounding polygon of a detected object on a plane. +// On output both vertices and normalized_vertices are provided. +// The polygon is formed by connecting vertices in the order they are listed. +message BoundingPoly { + // Output only . The bounding polygon normalized vertices. + repeated NormalizedVertex normalized_vertices = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/image.proto b/google/cloud/automl_v1beta1/proto/image.proto new file mode 100644 index 00000000..960eaeb0 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/image.proto @@ -0,0 +1,193 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/annotation_spec.proto"; +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "ImageProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Dataset metadata that is specific to image classification. +message ImageClassificationDatasetMetadata { + // Required. Type of the classification problem. + ClassificationType classification_type = 1; +} + +// Dataset metadata specific to image object detection. +message ImageObjectDetectionDatasetMetadata { + +} + +// Model metadata for image classification. +message ImageClassificationModelMetadata { + // Optional. The ID of the `base` model. If it is specified, the new model + // will be created based on the `base` model. Otherwise, the new model will be + // created from scratch. The `base` model must be in the same + // `project` and `location` as the new model to create, and have the same + // `model_type`. + string base_model_id = 1; + + // Required. The train budget of creating this model, expressed in hours. The + // actual `train_cost` will be equal or less than this value. + int64 train_budget = 2; + + // Output only. The actual train cost of creating this model, expressed in + // hours. If this model is created from a `base` model, the train cost used + // to create the `base` model are not included. + int64 train_cost = 3; + + // Output only. The reason that this create model operation stopped, + // e.g. `BUDGET_REACHED`, `MODEL_CONVERGED`. + string stop_reason = 5; + + // Optional. Type of the model. The available values are: + // * `cloud` - Model to be used via prediction calls to AutoML API. + // This is the default value. + // * `mobile-low-latency-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. Expected to have low latency, but + // may have lower prediction quality than other models. + // * `mobile-versatile-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. + // * `mobile-high-accuracy-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. Expected to have a higher + // latency, but should also have a higher prediction quality + // than other models. + // * `mobile-core-ml-low-latency-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with Core + // ML afterwards. Expected to have low latency, but may have + // lower prediction quality than other models. + // * `mobile-core-ml-versatile-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with Core + // ML afterwards. + // * `mobile-core-ml-high-accuracy-1` - A model that, in addition to + // providing prediction via AutoML API, can also be exported + // (see [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile device with + // Core ML afterwards. Expected to have a higher latency, but + // should also have a higher prediction quality than other + // models. + string model_type = 7; + + // Output only. An approximate number of online prediction QPS that can + // be supported by this model per each node on which it is deployed. + double node_qps = 13; + + // Output only. The number of nodes this model is deployed on. A node is an + // abstraction of a machine resource, which can handle online prediction QPS + // as given in the node_qps field. + int64 node_count = 14; +} + +// Model metadata specific to image object detection. +message ImageObjectDetectionModelMetadata { + // Optional. Type of the model. The available values are: + // * `cloud-high-accuracy-1` - (default) A model to be used via prediction + // calls to AutoML API. Expected to have a higher latency, but + // should also have a higher prediction quality than other + // models. + // * `cloud-low-latency-1` - A model to be used via prediction + // calls to AutoML API. Expected to have low latency, but may + // have lower prediction quality than other models. + // * `mobile-low-latency-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. Expected to have low latency, but + // may have lower prediction quality than other models. + // * `mobile-versatile-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. + // * `mobile-high-accuracy-1` - A model that, in addition to providing + // prediction via AutoML API, can also be exported (see + // [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]) and used on a mobile or edge device + // with TensorFlow afterwards. Expected to have a higher + // latency, but should also have a higher prediction quality + // than other models. + string model_type = 1; + + // Output only. The number of nodes this model is deployed on. A node is an + // abstraction of a machine resource, which can handle online prediction QPS + // as given in the qps_per_node field. + int64 node_count = 3; + + // Output only. An approximate number of online prediction QPS that can + // be supported by this model per each node on which it is deployed. + double node_qps = 4; + + // Output only. The reason that this create model operation stopped, + // e.g. `BUDGET_REACHED`, `MODEL_CONVERGED`. + string stop_reason = 5; + + // The train budget of creating this model, expressed in milli node + // hours i.e. 1,000 value in this field means 1 node hour. The actual + // `train_cost` will be equal or less than this value. If further model + // training ceases to provide any improvements, it will stop without using + // full budget and the stop_reason will be `MODEL_CONVERGED`. + // Note, node_hour = actual_hour * number_of_nodes_invovled. + // For model type `cloud-high-accuracy-1`(default) and `cloud-low-latency-1`, + // the train budget must be between 20,000 and 900,000 milli node hours, + // inclusive. The default value is 216, 000 which represents one day in + // wall time. + // For model type `mobile-low-latency-1`, `mobile-versatile-1`, + // `mobile-high-accuracy-1`, `mobile-core-ml-low-latency-1`, + // `mobile-core-ml-versatile-1`, `mobile-core-ml-high-accuracy-1`, the train + // budget must be between 1,000 and 100,000 milli node hours, inclusive. + // The default value is 24, 000 which represents one day in wall time. + int64 train_budget_milli_node_hours = 6; + + // Output only. The actual train cost of creating this model, expressed in + // milli node hours, i.e. 1,000 value in this field means 1 node hour. + // Guaranteed to not exceed the train budget. + int64 train_cost_milli_node_hours = 7; +} + +// Model deployment metadata specific to Image Classification. +message ImageClassificationModelDeploymentMetadata { + // Input only. The number of nodes to deploy the model on. A node is an + // abstraction of a machine resource, which can handle online prediction QPS + // as given in the model's + // + // [node_qps][google.cloud.automl.v1beta1.ImageClassificationModelMetadata.node_qps]. + // Must be between 1 and 100, inclusive on both ends. + int64 node_count = 1; +} + +// Model deployment metadata specific to Image Object Detection. +message ImageObjectDetectionModelDeploymentMetadata { + // Input only. The number of nodes to deploy the model on. A node is an + // abstraction of a machine resource, which can handle online prediction QPS + // as given in the model's + // + // [qps_per_node][google.cloud.automl.v1beta1.ImageObjectDetectionModelMetadata.qps_per_node]. + // Must be between 1 and 100, inclusive on both ends. + int64 node_count = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/io.proto b/google/cloud/automl_v1beta1/proto/io.proto new file mode 100644 index 00000000..a9979383 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/io.proto @@ -0,0 +1,1132 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Input configuration for ImportData Action. +// +// The format of input depends on dataset_metadata the Dataset into which +// the import is happening has. As input source the +// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] +// is expected, unless specified otherwise. Additionally any input .CSV file +// by itself must be 100MB or smaller, unless specified otherwise. +// If an "example" file (that is, image, video etc.) with identical content +// (even if it had different GCS_FILE_PATH) is mentioned multiple times, then +// its label, bounding boxes etc. are appended. The same file should be always +// provided with the same ML_USE and GCS_FILE_PATH, if it is not, then +// these values are nondeterministically selected from the given ones. +// +// The formats are represented in EBNF with commas being literal and with +// non-terminal symbols defined near the end of this comment. The formats are: +// +// * For Image Classification: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH,LABEL,LABEL,... +// GCS_FILE_PATH leads to image of up to 30MB in size. Supported +// extensions: .JPEG, .GIF, .PNG, .WEBP, .BMP, .TIFF, .ICO +// For MULTICLASS classification type, at most one LABEL is allowed +// per image. If an image has not yet been labeled, then it should be +// mentioned just once with no LABEL. +// Some sample rows: +// TRAIN,gs://folder/image1.jpg,daisy +// TEST,gs://folder/image2.jpg,dandelion,tulip,rose +// UNASSIGNED,gs://folder/image3.jpg,daisy +// UNASSIGNED,gs://folder/image4.jpg +// +// * For Image Object Detection: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH,(LABEL,BOUNDING_BOX | ,,,,,,,) +// GCS_FILE_PATH leads to image of up to 30MB in size. Supported +// extensions: .JPEG, .GIF, .PNG. +// Each image is assumed to be exhaustively labeled. The minimum +// allowed BOUNDING_BOX edge length is 0.01, and no more than 500 +// BOUNDING_BOX-es per image are allowed (one BOUNDING_BOX is defined +// per line). If an image has not yet been labeled, then it should be +// mentioned just once with no LABEL and the ",,,,,,," in place of the +// BOUNDING_BOX. For images which are known to not contain any +// bounding boxes, they should be labelled explictly as +// "NEGATIVE_IMAGE", followed by ",,,,,,," in place of the +// BOUNDING_BOX. +// Sample rows: +// TRAIN,gs://folder/image1.png,car,0.1,0.1,,,0.3,0.3,, +// TRAIN,gs://folder/image1.png,bike,.7,.6,,,.8,.9,, +// UNASSIGNED,gs://folder/im2.png,car,0.1,0.1,0.2,0.1,0.2,0.3,0.1,0.3 +// TEST,gs://folder/im3.png,,,,,,,,, +// TRAIN,gs://folder/im4.png,NEGATIVE_IMAGE,,,,,,,,, +// +// * For Video Classification: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH +// where ML_USE VALIDATE value should not be used. The GCS_FILE_PATH +// should lead to another .csv file which describes examples that have +// given ML_USE, using the following row format: +// GCS_FILE_PATH,(LABEL,TIME_SEGMENT_START,TIME_SEGMENT_END | ,,) +// Here GCS_FILE_PATH leads to a video of up to 50GB in size and up +// to 3h duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. +// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the +// length of the video, and end has to be after the start. Any segment +// of a video which has one or more labels on it, is considered a +// hard negative for all other labels. Any segment with no labels on +// it is considered to be unknown. If a whole video is unknown, then +// it shuold be mentioned just once with ",," in place of LABEL, +// TIME_SEGMENT_START,TIME_SEGMENT_END. +// Sample top level CSV file: +// TRAIN,gs://folder/train_videos.csv +// TEST,gs://folder/test_videos.csv +// UNASSIGNED,gs://folder/other_videos.csv +// Sample rows of a CSV file for a particular ML_USE: +// gs://folder/video1.avi,car,120,180.000021 +// gs://folder/video1.avi,bike,150,180.000021 +// gs://folder/vid2.avi,car,0,60.5 +// gs://folder/vid3.avi,,, +// +// * For Video Object Tracking: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH +// where ML_USE VALIDATE value should not be used. The GCS_FILE_PATH +// should lead to another .csv file which describes examples that have +// given ML_USE, using one of the following row format: +// GCS_FILE_PATH,LABEL,[INSTANCE_ID],TIMESTAMP,BOUNDING_BOX +// or +// GCS_FILE_PATH,,,,,,,,,, +// Here GCS_FILE_PATH leads to a video of up to 50GB in size and up +// to 3h duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. +// Providing INSTANCE_IDs can help to obtain a better model. When +// a specific labeled entity leaves the video frame, and shows up +// afterwards it is not required, albeit preferable, that the same +// INSTANCE_ID is given to it. +// TIMESTAMP must be within the length of the video, the +// BOUNDING_BOX is assumed to be drawn on the closest video's frame +// to the TIMESTAMP. Any mentioned by the TIMESTAMP frame is expected +// to be exhaustively labeled and no more than 500 BOUNDING_BOX-es per +// frame are allowed. If a whole video is unknown, then it should be +// mentioned just once with ",,,,,,,,,," in place of LABEL, +// [INSTANCE_ID],TIMESTAMP,BOUNDING_BOX. +// Sample top level CSV file: +// TRAIN,gs://folder/train_videos.csv +// TEST,gs://folder/test_videos.csv +// UNASSIGNED,gs://folder/other_videos.csv +// Seven sample rows of a CSV file for a particular ML_USE: +// gs://folder/video1.avi,car,1,12.10,0.8,0.8,0.9,0.8,0.9,0.9,0.8,0.9 +// gs://folder/video1.avi,car,1,12.90,0.4,0.8,0.5,0.8,0.5,0.9,0.4,0.9 +// gs://folder/video1.avi,car,2,12.10,.4,.2,.5,.2,.5,.3,.4,.3 +// gs://folder/video1.avi,car,2,12.90,.8,.2,,,.9,.3,, +// gs://folder/video1.avi,bike,,12.50,.45,.45,,,.55,.55,, +// gs://folder/video2.avi,car,1,0,.1,.9,,,.9,.1,, +// gs://folder/video2.avi,,,,,,,,,,, +// * For Text Extraction: +// CSV file(s) with each line in format: +// ML_USE,GCS_FILE_PATH +// GCS_FILE_PATH leads to a .JSONL (that is, JSON Lines) file which +// either imports text in-line or as documents. Any given +// .JSONL file must be 100MB or smaller. +// The in-line .JSONL file contains, per line, a proto that wraps a +// TextSnippet proto (in json representation) followed by one or more +// AnnotationPayload protos (called annotations), which have +// display_name and text_extraction detail populated. The given text +// is expected to be annotated exhaustively, for example, if you look +// for animals and text contains "dolphin" that is not labeled, then +// "dolphin" is assumed to not be an animal. Any given text snippet +// content must be 10KB or smaller, and also be UTF-8 NFC encoded +// (ASCII already is). +// The document .JSONL file contains, per line, a proto that wraps a +// Document proto. The Document proto must have either document_text +// or input_config set. In document_text case, the Document proto may +// also contain the spatial information of the document, including +// layout, document dimension and page number. In input_config case, +// only PDF documents are supported now, and each document may be up +// to 2MB large. Currently, annotations on documents cannot be +// specified at import. +// Three sample CSV rows: +// TRAIN,gs://folder/file1.jsonl +// VALIDATE,gs://folder/file2.jsonl +// TEST,gs://folder/file3.jsonl +// Sample in-line JSON Lines file for entity extraction (presented here +// with artificial line breaks, but the only actual line break is +// denoted by \n).: +// { +// "document": { +// "document_text": {"content": "dog cat"} +// "layout": [ +// { +// "text_segment": { +// "start_offset": 0, +// "end_offset": 3, +// }, +// "page_number": 1, +// "bounding_poly": { +// "normalized_vertices": [ +// {"x": 0.1, "y": 0.1}, +// {"x": 0.1, "y": 0.3}, +// {"x": 0.3, "y": 0.3}, +// {"x": 0.3, "y": 0.1}, +// ], +// }, +// "text_segment_type": TOKEN, +// }, +// { +// "text_segment": { +// "start_offset": 4, +// "end_offset": 7, +// }, +// "page_number": 1, +// "bounding_poly": { +// "normalized_vertices": [ +// {"x": 0.4, "y": 0.1}, +// {"x": 0.4, "y": 0.3}, +// {"x": 0.8, "y": 0.3}, +// {"x": 0.8, "y": 0.1}, +// ], +// }, +// "text_segment_type": TOKEN, +// } +// +// ], +// "document_dimensions": { +// "width": 8.27, +// "height": 11.69, +// "unit": INCH, +// } +// "page_count": 1, +// }, +// "annotations": [ +// { +// "display_name": "animal", +// "text_extraction": {"text_segment": {"start_offset": 0, +// "end_offset": 3}} +// }, +// { +// "display_name": "animal", +// "text_extraction": {"text_segment": {"start_offset": 4, +// "end_offset": 7}} +// } +// ], +// }\n +// { +// "text_snippet": { +// "content": "This dog is good." +// }, +// "annotations": [ +// { +// "display_name": "animal", +// "text_extraction": { +// "text_segment": {"start_offset": 5, "end_offset": 8} +// } +// } +// ] +// } +// Sample document JSON Lines file (presented here with artificial line +// breaks, but the only actual line break is denoted by \n).: +// { +// "document": { +// "input_config": { +// "gcs_source": { "input_uris": [ "gs://folder/document1.pdf" ] +// } +// } +// } +// }\n +// { +// "document": { +// "input_config": { +// "gcs_source": { "input_uris": [ "gs://folder/document2.pdf" ] +// } +// } +// } +// } +// +// * For Text Classification: +// CSV file(s) with each line in format: +// ML_USE,(TEXT_SNIPPET | GCS_FILE_PATH),LABEL,LABEL,... +// TEXT_SNIPPET and GCS_FILE_PATH are distinguished by a pattern. If +// the column content is a valid gcs file path, i.e. prefixed by +// "gs://", it will be treated as a GCS_FILE_PATH, else if the content +// is enclosed within double quotes (""), it is +// treated as a TEXT_SNIPPET. In the GCS_FILE_PATH case, the path +// must lead to a .txt file with UTF-8 encoding, for example, +// "gs://folder/content.txt", and the content in it is extracted +// as a text snippet. In TEXT_SNIPPET case, the column content +// excluding quotes is treated as to be imported text snippet. In +// both cases, the text snippet/file size must be within 128kB. +// Maximum 100 unique labels are allowed per CSV row. +// Sample rows: +// TRAIN,"They have bad food and very rude",RudeService,BadFood +// TRAIN,gs://folder/content.txt,SlowService +// TEST,"Typically always bad service there.",RudeService +// VALIDATE,"Stomach ache to go.",BadFood +// +// * For Text Sentiment: +// CSV file(s) with each line in format: +// ML_USE,(TEXT_SNIPPET | GCS_FILE_PATH),SENTIMENT +// TEXT_SNIPPET and GCS_FILE_PATH are distinguished by a pattern. If +// the column content is a valid gcs file path, that is, prefixed by +// "gs://", it is treated as a GCS_FILE_PATH, otherwise it is treated +// as a TEXT_SNIPPET. In the GCS_FILE_PATH case, the path +// must lead to a .txt file with UTF-8 encoding, for example, +// "gs://folder/content.txt", and the content in it is extracted +// as a text snippet. In TEXT_SNIPPET case, the column content itself +// is treated as to be imported text snippet. In both cases, the +// text snippet must be up to 500 characters long. +// Sample rows: +// TRAIN,"@freewrytin this is way too good for your product",2 +// TRAIN,"I need this product so bad",3 +// TEST,"Thank you for this product.",4 +// VALIDATE,gs://folder/content.txt,2 +// +// * For Tables: +// Either +// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] or +// +// [bigquery_source][google.cloud.automl.v1beta1.InputConfig.bigquery_source] +// can be used. All inputs is concatenated into a single +// +// [primary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_name] +// For gcs_source: +// CSV file(s), where the first row of the first file is the header, +// containing unique column names. If the first row of a subsequent +// file is the same as the header, then it is also treated as a +// header. All other rows contain values for the corresponding +// columns. +// Each .CSV file by itself must be 10GB or smaller, and their total +// size must be 100GB or smaller. +// First three sample rows of a CSV file: +// "Id","First Name","Last Name","Dob","Addresses" +// +// "1","John","Doe","1968-01-22","[{"status":"current","address":"123_First_Avenue","city":"Seattle","state":"WA","zip":"11111","numberOfYears":"1"},{"status":"previous","address":"456_Main_Street","city":"Portland","state":"OR","zip":"22222","numberOfYears":"5"}]" +// +// "2","Jane","Doe","1980-10-16","[{"status":"current","address":"789_Any_Avenue","city":"Albany","state":"NY","zip":"33333","numberOfYears":"2"},{"status":"previous","address":"321_Main_Street","city":"Hoboken","state":"NJ","zip":"44444","numberOfYears":"3"}]} +// For bigquery_source: +// An URI of a BigQuery table. The user data size of the BigQuery +// table must be 100GB or smaller. +// An imported table must have between 2 and 1,000 columns, inclusive, +// and between 1000 and 100,000,000 rows, inclusive. There are at most 5 +// import data running in parallel. +// Definitions: +// ML_USE = "TRAIN" | "VALIDATE" | "TEST" | "UNASSIGNED" +// Describes how the given example (file) should be used for model +// training. "UNASSIGNED" can be used when user has no preference. +// GCS_FILE_PATH = A path to file on GCS, e.g. "gs://folder/image1.png". +// LABEL = A display name of an object on an image, video etc., e.g. "dog". +// Must be up to 32 characters long and can consist only of ASCII +// Latin letters A-Z and a-z, underscores(_), and ASCII digits 0-9. +// For each label an AnnotationSpec is created which display_name +// becomes the label; AnnotationSpecs are given back in predictions. +// INSTANCE_ID = A positive integer that identifies a specific instance of a +// labeled entity on an example. Used e.g. to track two cars on +// a video while being able to tell apart which one is which. +// BOUNDING_BOX = VERTEX,VERTEX,VERTEX,VERTEX | VERTEX,,,VERTEX,, +// A rectangle parallel to the frame of the example (image, +// video). If 4 vertices are given they are connected by edges +// in the order provided, if 2 are given they are recognized +// as diagonally opposite vertices of the rectangle. +// VERTEX = COORDINATE,COORDINATE +// First coordinate is horizontal (x), the second is vertical (y). +// COORDINATE = A float in 0 to 1 range, relative to total length of +// image or video in given dimension. For fractions the +// leading non-decimal 0 can be omitted (i.e. 0.3 = .3). +// Point 0,0 is in top left. +// TIME_SEGMENT_START = TIME_OFFSET +// Expresses a beginning, inclusive, of a time segment +// within an example that has a time dimension +// (e.g. video). +// TIME_SEGMENT_END = TIME_OFFSET +// Expresses an end, exclusive, of a time segment within +// an example that has a time dimension (e.g. video). +// TIME_OFFSET = A number of seconds as measured from the start of an +// example (e.g. video). Fractions are allowed, up to a +// microsecond precision. "inf" is allowed, and it means the end +// of the example. +// TEXT_SNIPPET = A content of a text snippet, UTF-8 encoded, enclosed within +// double quotes (""). +// SENTIMENT = An integer between 0 and +// Dataset.text_sentiment_dataset_metadata.sentiment_max +// (inclusive). Describes the ordinal of the sentiment - higher +// value means a more positive sentiment. All the values are +// completely relative, i.e. neither 0 needs to mean a negative or +// neutral sentiment nor sentiment_max needs to mean a positive one +// - it is just required that 0 is the least positive sentiment +// in the data, and sentiment_max is the most positive one. +// The SENTIMENT shouldn't be confused with "score" or "magnitude" +// from the previous Natural Language Sentiment Analysis API. +// All SENTIMENT values between 0 and sentiment_max must be +// represented in the imported data. On prediction the same 0 to +// sentiment_max range will be used. The difference between +// neighboring sentiment values needs not to be uniform, e.g. 1 and +// 2 may be similar whereas the difference between 2 and 3 may be +// huge. +// +// Errors: +// If any of the provided CSV files can't be parsed or if more than certain +// percent of CSV rows cannot be processed then the operation fails and +// nothing is imported. Regardless of overall success or failure the per-row +// failures, up to a certain count cap, is listed in +// Operation.metadata.partial_failures. +// +message InputConfig { + // The source of the input. + oneof source { + // The Google Cloud Storage location for the input content. + // In ImportData, the gcs_source points to a csv with structure described in + // the comment. + GcsSource gcs_source = 1; + + // The BigQuery location for the input content. + BigQuerySource bigquery_source = 3; + } + + // Additional domain-specific parameters describing the semantic of the + // imported data, any string must be up to 25000 + // characters long. + // + // * For Tables: + // `schema_inference_version` - (integer) Required. The version of the + // algorithm that should be used for the initial inference of the + // schema (columns' DataTypes) of the table the data is being imported + // into. Allowed values: "1". + map params = 2; +} + +// Input configuration for BatchPredict Action. +// +// The format of input depends on the ML problem of the model used for +// prediction. As input source the +// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] +// is expected, unless specified otherwise. +// +// The formats are represented in EBNF with commas being literal and with +// non-terminal symbols defined near the end of this comment. The formats +// are: +// +// * For Image Classification: +// CSV file(s) with each line having just a single column: +// GCS_FILE_PATH +// which leads to image of up to 30MB in size. Supported +// extensions: .JPEG, .GIF, .PNG. This path is treated as the ID in +// the Batch predict output. +// Three sample rows: +// gs://folder/image1.jpeg +// gs://folder/image2.gif +// gs://folder/image3.png +// +// * For Image Object Detection: +// CSV file(s) with each line having just a single column: +// GCS_FILE_PATH +// which leads to image of up to 30MB in size. Supported +// extensions: .JPEG, .GIF, .PNG. This path is treated as the ID in +// the Batch predict output. +// Three sample rows: +// gs://folder/image1.jpeg +// gs://folder/image2.gif +// gs://folder/image3.png +// * For Video Classification: +// CSV file(s) with each line in format: +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END +// GCS_FILE_PATH leads to video of up to 50GB in size and up to 3h +// duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. +// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the +// length of the video, and end has to be after the start. +// Three sample rows: +// gs://folder/video1.mp4,10,40 +// gs://folder/video1.mp4,20,60 +// gs://folder/vid2.mov,0,inf +// +// * For Video Object Tracking: +// CSV file(s) with each line in format: +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END +// GCS_FILE_PATH leads to video of up to 50GB in size and up to 3h +// duration. Supported extensions: .MOV, .MPEG4, .MP4, .AVI. +// TIME_SEGMENT_START and TIME_SEGMENT_END must be within the +// length of the video, and end has to be after the start. +// Three sample rows: +// gs://folder/video1.mp4,10,240 +// gs://folder/video1.mp4,300,360 +// gs://folder/vid2.mov,0,inf +// * For Text Classification: +// CSV file(s) with each line having just a single column: +// GCS_FILE_PATH | TEXT_SNIPPET +// Any given text file can have size upto 128kB. +// Any given text snippet content must have 60,000 characters or less. +// Three sample rows: +// gs://folder/text1.txt +// "Some text content to predict" +// gs://folder/text3.pdf +// Supported file extensions: .txt, .pdf +// +// * For Text Sentiment: +// CSV file(s) with each line having just a single column: +// GCS_FILE_PATH | TEXT_SNIPPET +// Any given text file can have size upto 128kB. +// Any given text snippet content must have 500 characters or less. +// Three sample rows: +// gs://folder/text1.txt +// "Some text content to predict" +// gs://folder/text3.pdf +// Supported file extensions: .txt, .pdf +// +// * For Text Extraction +// .JSONL (i.e. JSON Lines) file(s) which either provide text in-line or +// as documents (for a single BatchPredict call only one of the these +// formats may be used). +// The in-line .JSONL file(s) contain per line a proto that +// wraps a temporary user-assigned TextSnippet ID (string up to 2000 +// characters long) called "id", a TextSnippet proto (in +// json representation) and zero or more TextFeature protos. Any given +// text snippet content must have 30,000 characters or less, and also +// be UTF-8 NFC encoded (ASCII already is). The IDs provided should be +// unique. +// The document .JSONL file(s) contain, per line, a proto that wraps a +// Document proto with input_config set. Only PDF documents are +// supported now, and each document must be up to 2MB large. +// Any given .JSONL file must be 100MB or smaller, and no more than 20 +// files may be given. +// Sample in-line JSON Lines file (presented here with artificial line +// breaks, but the only actual line break is denoted by \n): +// { +// "id": "my_first_id", +// "text_snippet": { "content": "dog car cat"}, +// "text_features": [ +// { +// "text_segment": {"start_offset": 4, "end_offset": 6}, +// "structural_type": PARAGRAPH, +// "bounding_poly": { +// "normalized_vertices": [ +// {"x": 0.1, "y": 0.1}, +// {"x": 0.1, "y": 0.3}, +// {"x": 0.3, "y": 0.3}, +// {"x": 0.3, "y": 0.1}, +// ] +// }, +// } +// ], +// }\n +// { +// "id": "2", +// "text_snippet": { +// "content": "An elaborate content", +// "mime_type": "text/plain" +// } +// } +// Sample document JSON Lines file (presented here with artificial line +// breaks, but the only actual line break is denoted by \n).: +// { +// "document": { +// "input_config": { +// "gcs_source": { "input_uris": [ "gs://folder/document1.pdf" ] +// } +// } +// } +// }\n +// { +// "document": { +// "input_config": { +// "gcs_source": { "input_uris": [ "gs://folder/document2.pdf" ] +// } +// } +// } +// } +// +// * For Tables: +// Either +// [gcs_source][google.cloud.automl.v1beta1.InputConfig.gcs_source] or +// +// [bigquery_source][google.cloud.automl.v1beta1.InputConfig.bigquery_source]. +// GCS case: +// CSV file(s), each by itself 10GB or smaller and total size must be +// 100GB or smaller, where first file must have a header containing +// column names. If the first row of a subsequent file is the same as +// the header, then it is also treated as a header. All other rows +// contain values for the corresponding columns. +// The column names must contain the model's +// +// [input_feature_column_specs'][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] +// +// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] +// (order doesn't matter). The columns corresponding to the model's +// input feature column specs must contain values compatible with the +// column spec's data types. Prediction on all the rows, i.e. the CSV +// lines, will be attempted. For FORECASTING +// +// [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: +// all columns having +// +// [TIME_SERIES_AVAILABLE_PAST_ONLY][google.cloud.automl.v1beta1.ColumnSpec.ForecastingMetadata.ColumnType] +// type will be ignored. +// First three sample rows of a CSV file: +// "First Name","Last Name","Dob","Addresses" +// +// "John","Doe","1968-01-22","[{"status":"current","address":"123_First_Avenue","city":"Seattle","state":"WA","zip":"11111","numberOfYears":"1"},{"status":"previous","address":"456_Main_Street","city":"Portland","state":"OR","zip":"22222","numberOfYears":"5"}]" +// +// "Jane","Doe","1980-10-16","[{"status":"current","address":"789_Any_Avenue","city":"Albany","state":"NY","zip":"33333","numberOfYears":"2"},{"status":"previous","address":"321_Main_Street","city":"Hoboken","state":"NJ","zip":"44444","numberOfYears":"3"}]} +// BigQuery case: +// An URI of a BigQuery table. The user data size of the BigQuery +// table must be 100GB or smaller. +// The column names must contain the model's +// +// [input_feature_column_specs'][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] +// +// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] +// (order doesn't matter). The columns corresponding to the model's +// input feature column specs must contain values compatible with the +// column spec's data types. Prediction on all the rows of the table +// will be attempted. For FORECASTING +// +// [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: +// all columns having +// +// [TIME_SERIES_AVAILABLE_PAST_ONLY][google.cloud.automl.v1beta1.ColumnSpec.ForecastingMetadata.ColumnType] +// type will be ignored. +// +// Definitions: +// GCS_FILE_PATH = A path to file on GCS, e.g. "gs://folder/video.avi". +// TEXT_SNIPPET = A content of a text snippet, UTF-8 encoded, enclosed within +// double quotes ("") +// TIME_SEGMENT_START = TIME_OFFSET +// Expresses a beginning, inclusive, of a time segment +// within an +// example that has a time dimension (e.g. video). +// TIME_SEGMENT_END = TIME_OFFSET +// Expresses an end, exclusive, of a time segment within +// an example that has a time dimension (e.g. video). +// TIME_OFFSET = A number of seconds as measured from the start of an +// example (e.g. video). Fractions are allowed, up to a +// microsecond precision. "inf" is allowed and it means the end +// of the example. +// +// Errors: +// If any of the provided CSV files can't be parsed or if more than certain +// percent of CSV rows cannot be processed then the operation fails and +// prediction does not happen. Regardless of overall success or failure the +// per-row failures, up to a certain count cap, will be listed in +// Operation.metadata.partial_failures. +message BatchPredictInputConfig { + // Required. The source of the input. + oneof source { + // The Google Cloud Storage location for the input content. + GcsSource gcs_source = 1; + + // The BigQuery location for the input content. + BigQuerySource bigquery_source = 2; + } +} + +// Input configuration of a [Document][google.cloud.automl.v1beta1.Document]. +message DocumentInputConfig { + // The Google Cloud Storage location of the document file. Only a single path + // should be given. + // Max supported size: 512MB. + // Supported extensions: .PDF. + GcsSource gcs_source = 1; +} + +// * For Translation: +// CSV file `translation.csv`, with each line in format: +// ML_USE,GCS_FILE_PATH +// GCS_FILE_PATH leads to a .TSV file which describes examples that have +// given ML_USE, using the following row format per line: +// TEXT_SNIPPET (in source language) \t TEXT_SNIPPET (in target +// language) +// +// * For Tables: +// Output depends on whether the dataset was imported from GCS or +// BigQuery. +// GCS case: +// +// [gcs_destination][google.cloud.automl.v1beta1.OutputConfig.gcs_destination] +// must be set. Exported are CSV file(s) `tables_1.csv`, +// `tables_2.csv`,...,`tables_N.csv` with each having as header line +// the table's column names, and all other lines contain values for +// the header columns. +// BigQuery case: +// +// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] +// pointing to a BigQuery project must be set. In the given project a +// new dataset will be created with name +// +// `export_data__` +// where will be made +// BigQuery-dataset-name compatible (e.g. most special characters will +// become underscores), and timestamp will be in +// YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" format. In that +// dataset a new table called `primary_table` will be created, and +// filled with precisely the same data as this obtained on import. +message OutputConfig { + // Required. The destination of the output. + oneof destination { + // The Google Cloud Storage location where the output is to be written to. + // For Image Object Detection, Text Extraction, Video Classification and + // Tables, in the given directory a new directory will be created with name: + // export_data-- where + // timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format. All export + // output will be written into that directory. + GcsDestination gcs_destination = 1; + + // The BigQuery location where the output is to be written to. + BigQueryDestination bigquery_destination = 2; + } +} + +// Output configuration for BatchPredict Action. +// +// As destination the +// +// [gcs_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.gcs_destination] +// must be set unless specified otherwise for a domain. If gcs_destination is +// set then in the given directory a new directory is created. Its name +// will be +// "prediction--", +// where timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format. The contents +// of it depends on the ML problem the predictions are made for. +// +// * For Image Classification: +// In the created directory files `image_classification_1.jsonl`, +// `image_classification_2.jsonl`,...,`image_classification_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of the successfully predicted images and annotations. +// A single image will be listed only once with all its annotations, +// and its annotations will never be split across files. +// Each .JSONL file will contain, per line, a JSON representation of a +// proto that wraps image's "ID" : "" followed by a list of +// zero or more AnnotationPayload protos (called annotations), which +// have classification detail populated. +// If prediction for any image failed (partially or completely), then an +// additional `errors_1.jsonl`, `errors_2.jsonl`,..., `errors_N.jsonl` +// files will be created (N depends on total number of failed +// predictions). These files will have a JSON representation of a proto +// that wraps the same "ID" : "" but here followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`fields. +// +// * For Image Object Detection: +// In the created directory files `image_object_detection_1.jsonl`, +// `image_object_detection_2.jsonl`,...,`image_object_detection_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of the successfully predicted images and annotations. +// Each .JSONL file will contain, per line, a JSON representation of a +// proto that wraps image's "ID" : "" followed by a list of +// zero or more AnnotationPayload protos (called annotations), which +// have image_object_detection detail populated. A single image will +// be listed only once with all its annotations, and its annotations +// will never be split across files. +// If prediction for any image failed (partially or completely), then +// additional `errors_1.jsonl`, `errors_2.jsonl`,..., `errors_N.jsonl` +// files will be created (N depends on total number of failed +// predictions). These files will have a JSON representation of a proto +// that wraps the same "ID" : "" but here followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`fields. +// * For Video Classification: +// In the created directory a video_classification.csv file, and a .JSON +// file per each video classification requested in the input (i.e. each +// line in given CSV(s)), will be created. +// +// The format of video_classification.csv is: +// +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END,JSON_FILE_NAME,STATUS +// where: +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END = matches 1 to 1 +// the prediction input lines (i.e. video_classification.csv has +// precisely the same number of lines as the prediction input had.) +// JSON_FILE_NAME = Name of .JSON file in the output directory, which +// contains prediction responses for the video time segment. +// STATUS = "OK" if prediction completed successfully, or an error code +// with message otherwise. If STATUS is not "OK" then the .JSON file +// for that line may not exist or be empty. +// +// Each .JSON file, assuming STATUS is "OK", will contain a list of +// AnnotationPayload protos in JSON format, which are the predictions +// for the video time segment the file is assigned to in the +// video_classification.csv. All AnnotationPayload protos will have +// video_classification field set, and will be sorted by +// video_classification.type field (note that the returned types are +// governed by `classifaction_types` parameter in +// [PredictService.BatchPredictRequest.params][]). +// +// * For Video Object Tracking: +// In the created directory a video_object_tracking.csv file will be +// created, and multiple files video_object_trackinng_1.json, +// video_object_trackinng_2.json,..., video_object_trackinng_N.json, +// where N is the number of requests in the input (i.e. the number of +// lines in given CSV(s)). +// +// The format of video_object_tracking.csv is: +// +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END,JSON_FILE_NAME,STATUS +// where: +// GCS_FILE_PATH,TIME_SEGMENT_START,TIME_SEGMENT_END = matches 1 to 1 +// the prediction input lines (i.e. video_object_tracking.csv has +// precisely the same number of lines as the prediction input had.) +// JSON_FILE_NAME = Name of .JSON file in the output directory, which +// contains prediction responses for the video time segment. +// STATUS = "OK" if prediction completed successfully, or an error +// code with message otherwise. If STATUS is not "OK" then the .JSON +// file for that line may not exist or be empty. +// +// Each .JSON file, assuming STATUS is "OK", will contain a list of +// AnnotationPayload protos in JSON format, which are the predictions +// for each frame of the video time segment the file is assigned to in +// video_object_tracking.csv. All AnnotationPayload protos will have +// video_object_tracking field set. +// * For Text Classification: +// In the created directory files `text_classification_1.jsonl`, +// `text_classification_2.jsonl`,...,`text_classification_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of inputs and annotations found. +// +// Each .JSONL file will contain, per line, a JSON representation of a +// proto that wraps input text snippet or input text file and a list of +// zero or more AnnotationPayload protos (called annotations), which +// have classification detail populated. A single text snippet or file +// will be listed only once with all its annotations, and its +// annotations will never be split across files. +// +// If prediction for any text snippet or file failed (partially or +// completely), then additional `errors_1.jsonl`, `errors_2.jsonl`,..., +// `errors_N.jsonl` files will be created (N depends on total number of +// failed predictions). These files will have a JSON representation of a +// proto that wraps input text snippet or input text file followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`. +// +// * For Text Sentiment: +// In the created directory files `text_sentiment_1.jsonl`, +// `text_sentiment_2.jsonl`,...,`text_sentiment_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of inputs and annotations found. +// +// Each .JSONL file will contain, per line, a JSON representation of a +// proto that wraps input text snippet or input text file and a list of +// zero or more AnnotationPayload protos (called annotations), which +// have text_sentiment detail populated. A single text snippet or file +// will be listed only once with all its annotations, and its +// annotations will never be split across files. +// +// If prediction for any text snippet or file failed (partially or +// completely), then additional `errors_1.jsonl`, `errors_2.jsonl`,..., +// `errors_N.jsonl` files will be created (N depends on total number of +// failed predictions). These files will have a JSON representation of a +// proto that wraps input text snippet or input text file followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`. +// +// * For Text Extraction: +// In the created directory files `text_extraction_1.jsonl`, +// `text_extraction_2.jsonl`,...,`text_extraction_N.jsonl` +// will be created, where N may be 1, and depends on the +// total number of inputs and annotations found. +// The contents of these .JSONL file(s) depend on whether the input +// used inline text, or documents. +// If input was inline, then each .JSONL file will contain, per line, +// a JSON representation of a proto that wraps given in request text +// snippet's "id" (if specified), followed by input text snippet, +// and a list of zero or more +// AnnotationPayload protos (called annotations), which have +// text_extraction detail populated. A single text snippet will be +// listed only once with all its annotations, and its annotations will +// never be split across files. +// If input used documents, then each .JSONL file will contain, per +// line, a JSON representation of a proto that wraps given in request +// document proto, followed by its OCR-ed representation in the form +// of a text snippet, finally followed by a list of zero or more +// AnnotationPayload protos (called annotations), which have +// text_extraction detail populated and refer, via their indices, to +// the OCR-ed text snippet. A single document (and its text snippet) +// will be listed only once with all its annotations, and its +// annotations will never be split across files. +// If prediction for any text snippet failed (partially or completely), +// then additional `errors_1.jsonl`, `errors_2.jsonl`,..., +// `errors_N.jsonl` files will be created (N depends on total number of +// failed predictions). These files will have a JSON representation of a +// proto that wraps either the "id" : "" (in case of inline) +// or the document proto (in case of document) but here followed by +// exactly one +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// containing only `code` and `message`. +// +// * For Tables: +// Output depends on whether +// +// [gcs_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.gcs_destination] +// or +// +// [bigquery_destination][google.cloud.automl.v1beta1.BatchPredictOutputConfig.bigquery_destination] +// is set (either is allowed). +// GCS case: +// In the created directory files `tables_1.csv`, `tables_2.csv`,..., +// `tables_N.csv` will be created, where N may be 1, and depends on +// the total number of the successfully predicted rows. +// For all CLASSIFICATION +// +// [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: +// Each .csv file will contain a header, listing all columns' +// +// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] +// given on input followed by M target column names in the format of +// +// "<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] +// +// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>__score" where M is the number of distinct target values, +// i.e. number of distinct values in the target column of the table +// used to train the model. Subsequent lines will contain the +// respective values of successfully predicted rows, with the last, +// i.e. the target, columns having the corresponding prediction +// [scores][google.cloud.automl.v1beta1.TablesAnnotation.score]. +// For REGRESSION and FORECASTING +// +// [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]: +// Each .csv file will contain a header, listing all columns' +// [display_name-s][google.cloud.automl.v1beta1.display_name] given +// on input followed by the predicted target column with name in the +// format of +// +// "predicted_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] +// +// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>" +// Subsequent lines will contain the respective values of +// successfully predicted rows, with the last, i.e. the target, +// column having the predicted target value. +// If prediction for any rows failed, then an additional +// `errors_1.csv`, `errors_2.csv`,..., `errors_N.csv` will be +// created (N depends on total number of failed rows). These files +// will have analogous format as `tables_*.csv`, but always with a +// single target column having +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// represented as a JSON string, and containing only `code` and +// `message`. +// BigQuery case: +// +// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] +// pointing to a BigQuery project must be set. In the given project a +// new dataset will be created with name +// `prediction__` +// where will be made +// BigQuery-dataset-name compatible (e.g. most special characters will +// become underscores), and timestamp will be in +// YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" format. In the dataset +// two tables will be created, `predictions`, and `errors`. +// The `predictions` table's column names will be the input columns' +// +// [display_name-s][google.cloud.automl.v1beta1.ColumnSpec.display_name] +// followed by the target column with name in the format of +// +// "predicted_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] +// +// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>" +// The input feature columns will contain the respective values of +// successfully predicted rows, with the target column having an +// ARRAY of +// +// [AnnotationPayloads][google.cloud.automl.v1beta1.AnnotationPayload], +// represented as STRUCT-s, containing +// [TablesAnnotation][google.cloud.automl.v1beta1.TablesAnnotation]. +// The `errors` table contains rows for which the prediction has +// failed, it has analogous input columns while the target column name +// is in the format of +// +// "errors_<[target_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] +// +// [display_name][google.cloud.automl.v1beta1.ColumnSpec.display_name]>", +// and as a value has +// +// [`google.rpc.Status`](https: +// //github.com/googleapis/googleapis/blob/master/google/rpc/status.proto) +// represented as a STRUCT, and containing only `code` and `message`. +message BatchPredictOutputConfig { + // Required. The destination of the output. + oneof destination { + // The Google Cloud Storage location of the directory where the output is to + // be written to. + GcsDestination gcs_destination = 1; + + // The BigQuery location where the output is to be written to. + BigQueryDestination bigquery_destination = 2; + } +} + +// Output configuration for ModelExport Action. +message ModelExportOutputConfig { + // Required. The destination of the output. + oneof destination { + // The Google Cloud Storage location where the model is to be written to. + // This location may only be set for the following model formats: + // "tflite", "edgetpu_tflite", "tf_saved_model", "tf_js", "core_ml". + // + // Under the directory given as the destination a new one with name + // "model-export--", + // where timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601 format, + // will be created. Inside the model and any of its supporting files + // will be written. + GcsDestination gcs_destination = 1; + + // The GCR location where model image is to be pushed to. This location + // may only be set for the following model formats: + // "docker". + // + // The model image will be created under the given URI. + GcrDestination gcr_destination = 3; + } + + // The format in which the model must be exported. The available, and default, + // formats depend on the problem and model type (if given problem and type + // combination doesn't have a format listed, it means its models are not + // exportable): + // + // * For Image Classification mobile-low-latency-1, mobile-versatile-1, + // mobile-high-accuracy-1: + // "tflite" (default), "edgetpu_tflite", "tf_saved_model", "tf_js", + // "docker". + // + // * For Image Classification mobile-core-ml-low-latency-1, + // mobile-core-ml-versatile-1, mobile-core-ml-high-accuracy-1: + // "core_ml" (default). + // Formats description: + // + // * tflite - Used for Android mobile devices. + // * edgetpu_tflite - Used for [Edge TPU](https://cloud.google.com/edge-tpu/) + // devices. + // * tf_saved_model - A tensorflow model in SavedModel format. + // * tf_js - A [TensorFlow.js](https://www.tensorflow.org/js) model that can + // be used in the browser and in Node.js using JavaScript. + // * docker - Used for Docker containers. Use the params field to customize + // the container. The container is verified to work correctly on + // ubuntu 16.04 operating system. See more at + // [containers + // + // quickstart](https: + // //cloud.google.com/vision/automl/docs/containers-gcs-quickstart) + // * core_ml - Used for iOS mobile devices. + string model_format = 4; + + // Additional model-type and format specific parameters describing the + // requirements for the to be exported model files, any string must be up to + // 25000 characters long. + // + // * For `docker` format: + // `cpu_architecture` - (string) "x86_64" (default). + // `gpu_architecture` - (string) "none" (default), "nvidia". + map params = 2; +} + +// Output configuration for ExportEvaluatedExamples Action. Note that this call +// is available only for 30 days since the moment the model was evaluated. +// The output depends on the domain, as follows (note that only examples from +// the TEST set are exported): +// +// * For Tables: +// +// [bigquery_destination][google.cloud.automl.v1beta1.OutputConfig.bigquery_destination] +// pointing to a BigQuery project must be set. In the given project a +// new dataset will be created with name +// +// `export_evaluated_examples__` +// where will be made BigQuery-dataset-name +// compatible (e.g. most special characters will become underscores), +// and timestamp will be in YYYY_MM_DDThh_mm_ss_sssZ "based on ISO-8601" +// format. In the dataset an `evaluated_examples` table will be +// created. It will have all the same columns as the +// +// [primary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_spec_id] +// of the +// [dataset][google.cloud.automl.v1beta1.Model.dataset_id] from which +// the model was created, as they were at the moment of model's +// evaluation (this includes the target column with its ground +// truth), followed by a column called "predicted_". That +// last column will contain the model's prediction result for each +// respective row, given as ARRAY of +// [AnnotationPayloads][google.cloud.automl.v1beta1.AnnotationPayload], +// represented as STRUCT-s, containing +// [TablesAnnotation][google.cloud.automl.v1beta1.TablesAnnotation]. +message ExportEvaluatedExamplesOutputConfig { + // Required. The destination of the output. + oneof destination { + // The BigQuery location where the output is to be written to. + BigQueryDestination bigquery_destination = 2; + } +} + +// The Google Cloud Storage location for the input content. +message GcsSource { + // Required. Google Cloud Storage URIs to input files, up to 2000 characters + // long. Accepted forms: + // * Full object path, e.g. gs://bucket/directory/object.csv + repeated string input_uris = 1; +} + +// The BigQuery location for the input content. +message BigQuerySource { + // Required. BigQuery URI to a table, up to 2000 characters long. + // Accepted forms: + // * BigQuery path e.g. bq://projectId.bqDatasetId.bqTableId + string input_uri = 1; +} + +// The Google Cloud Storage location where the output is to be written to. +message GcsDestination { + // Required. Google Cloud Storage URI to output directory, up to 2000 + // characters long. + // Accepted forms: + // * Prefix path: gs://bucket/directory + // The requesting user must have write permission to the bucket. + // The directory is created if it doesn't exist. + string output_uri_prefix = 1; +} + +// The BigQuery location for the output content. +message BigQueryDestination { + // Required. BigQuery URI to a project, up to 2000 characters long. + // Accepted forms: + // * BigQuery path e.g. bq://projectId + string output_uri = 1; +} + +// The GCR location where the image must be pushed to. +message GcrDestination { + // Required. Google Contained Registry URI of the new image, up to 2000 + // characters long. See + // + // https: + // //cloud.google.com/container-registry/do + // // cs/pushing-and-pulling#pushing_an_image_to_a_registry + // Accepted forms: + // * [HOSTNAME]/[PROJECT-ID]/[IMAGE] + // * [HOSTNAME]/[PROJECT-ID]/[IMAGE]:[TAG] + // + // The requesting user must have permission to push images the project. + string output_uri = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/model.proto b/google/cloud/automl_v1beta1/proto/model.proto new file mode 100644 index 00000000..2b2e8d73 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/model.proto @@ -0,0 +1,108 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/image.proto"; +import "google/cloud/automl/v1beta1/tables.proto"; +import "google/cloud/automl/v1beta1/text.proto"; +import "google/cloud/automl/v1beta1/translation.proto"; +import "google/cloud/automl/v1beta1/video.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// API proto representing a trained machine learning model. +message Model { + option (google.api.resource) = { + type: "automl.googleapis.com/Model" + pattern: "projects/{project}/locations/{location}/models/{model}" + }; + + // Deployment state of the model. + enum DeploymentState { + // Should not be used, an un-set enum has this value by default. + DEPLOYMENT_STATE_UNSPECIFIED = 0; + + // Model is deployed. + DEPLOYED = 1; + + // Model is not deployed. + UNDEPLOYED = 2; + } + + // Required. + // The model metadata that is specific to the problem type. + // Must match the metadata type of the dataset used to train the model. + oneof model_metadata { + // Metadata for translation models. + TranslationModelMetadata translation_model_metadata = 15; + + // Metadata for image classification models. + ImageClassificationModelMetadata image_classification_model_metadata = 13; + + // Metadata for text classification models. + TextClassificationModelMetadata text_classification_model_metadata = 14; + + // Metadata for image object detection models. + ImageObjectDetectionModelMetadata image_object_detection_model_metadata = 20; + + // Metadata for video classification models. + VideoClassificationModelMetadata video_classification_model_metadata = 23; + + // Metadata for video object tracking models. + VideoObjectTrackingModelMetadata video_object_tracking_model_metadata = 21; + + // Metadata for text extraction models. + TextExtractionModelMetadata text_extraction_model_metadata = 19; + + // Metadata for Tables models. + TablesModelMetadata tables_model_metadata = 24; + + // Metadata for text sentiment models. + TextSentimentModelMetadata text_sentiment_model_metadata = 22; + } + + // Output only. Resource name of the model. + // Format: `projects/{project_id}/locations/{location_id}/models/{model_id}` + string name = 1; + + // Required. The name of the model to show in the interface. The name can be + // up to 32 characters long and can consist only of ASCII Latin letters A-Z + // and a-z, underscores + // (_), and ASCII digits 0-9. It must start with a letter. + string display_name = 2; + + // Required. The resource ID of the dataset used to create the model. The dataset must + // come from the same ancestor project and location. + string dataset_id = 3; + + // Output only. Timestamp when the model training finished and can be used for prediction. + google.protobuf.Timestamp create_time = 7; + + // Output only. Timestamp when this model was last updated. + google.protobuf.Timestamp update_time = 11; + + // Output only. Deployment state of the model. A model can only serve + // prediction requests after it gets deployed. + DeploymentState deployment_state = 8; +} diff --git a/google/cloud/automl_v1beta1/proto/model_evaluation.proto b/google/cloud/automl_v1beta1/proto/model_evaluation.proto new file mode 100644 index 00000000..d5633fcd --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/model_evaluation.proto @@ -0,0 +1,116 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/cloud/automl/v1beta1/detection.proto"; +import "google/cloud/automl/v1beta1/regression.proto"; +import "google/cloud/automl/v1beta1/tables.proto"; +import "google/cloud/automl/v1beta1/text_extraction.proto"; +import "google/cloud/automl/v1beta1/text_sentiment.proto"; +import "google/cloud/automl/v1beta1/translation.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Evaluation results of a model. +message ModelEvaluation { + option (google.api.resource) = { + type: "automl.googleapis.com/ModelEvaluation" + pattern: "projects/{project}/locations/{location}/models/{model}/modelEvaluations/{model_evaluation}" + }; + + // Output only. Problem type specific evaluation metrics. + oneof metrics { + // Model evaluation metrics for image, text, video and tables + // classification. + // Tables problem is considered a classification when the target column + // is CATEGORY DataType. + ClassificationEvaluationMetrics classification_evaluation_metrics = 8; + + // Model evaluation metrics for Tables regression. + // Tables problem is considered a regression when the target column + // has FLOAT64 DataType. + RegressionEvaluationMetrics regression_evaluation_metrics = 24; + + // Model evaluation metrics for translation. + TranslationEvaluationMetrics translation_evaluation_metrics = 9; + + // Model evaluation metrics for image object detection. + ImageObjectDetectionEvaluationMetrics image_object_detection_evaluation_metrics = 12; + + // Model evaluation metrics for video object tracking. + VideoObjectTrackingEvaluationMetrics video_object_tracking_evaluation_metrics = 14; + + // Evaluation metrics for text sentiment models. + TextSentimentEvaluationMetrics text_sentiment_evaluation_metrics = 11; + + // Evaluation metrics for text extraction models. + TextExtractionEvaluationMetrics text_extraction_evaluation_metrics = 13; + } + + // Output only. Resource name of the model evaluation. + // Format: + // + // `projects/{project_id}/locations/{location_id}/models/{model_id}/modelEvaluations/{model_evaluation_id}` + string name = 1; + + // Output only. The ID of the annotation spec that the model evaluation applies to. The + // The ID is empty for the overall model evaluation. + // For Tables annotation specs in the dataset do not exist and this ID is + // always not set, but for CLASSIFICATION + // + // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] + // the + // [display_name][google.cloud.automl.v1beta1.ModelEvaluation.display_name] + // field is used. + string annotation_spec_id = 2; + + // Output only. The value of + // [display_name][google.cloud.automl.v1beta1.AnnotationSpec.display_name] at + // the moment when the model was trained. Because this field returns a value + // at model training time, for different models trained from the same dataset, + // the values may differ, since display names could had been changed between + // the two model's trainings. + // For Tables CLASSIFICATION + // + // [prediction_type-s][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type] + // distinct values of the target column at the moment of the model evaluation + // are populated here. + // The display_name is empty for the overall model evaluation. + string display_name = 15; + + // Output only. Timestamp when this model evaluation was created. + google.protobuf.Timestamp create_time = 5; + + // Output only. The number of examples used for model evaluation, i.e. for + // which ground truth from time of model creation is compared against the + // predicted annotations created by the model. + // For overall ModelEvaluation (i.e. with annotation_spec_id not set) this is + // the total number of all examples used for evaluation. + // Otherwise, this is the count of examples that according to the ground + // truth were annotated by the + // + // [annotation_spec_id][google.cloud.automl.v1beta1.ModelEvaluation.annotation_spec_id]. + int32 evaluated_example_count = 6; +} diff --git a/google/cloud/automl_v1beta1/proto/operations.proto b/google/cloud/automl_v1beta1/proto/operations.proto new file mode 100644 index 00000000..cce3fedc --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/operations.proto @@ -0,0 +1,189 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/io.proto"; +import "google/cloud/automl/v1beta1/model.proto"; +import "google/cloud/automl/v1beta1/model_evaluation.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; +import "google/rpc/status.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Metadata used across all long running operations returned by AutoML API. +message OperationMetadata { + // Ouptut only. Details of specific operation. Even if this field is empty, + // the presence allows to distinguish different types of operations. + oneof details { + // Details of a Delete operation. + DeleteOperationMetadata delete_details = 8; + + // Details of a DeployModel operation. + DeployModelOperationMetadata deploy_model_details = 24; + + // Details of an UndeployModel operation. + UndeployModelOperationMetadata undeploy_model_details = 25; + + // Details of CreateModel operation. + CreateModelOperationMetadata create_model_details = 10; + + // Details of ImportData operation. + ImportDataOperationMetadata import_data_details = 15; + + // Details of BatchPredict operation. + BatchPredictOperationMetadata batch_predict_details = 16; + + // Details of ExportData operation. + ExportDataOperationMetadata export_data_details = 21; + + // Details of ExportModel operation. + ExportModelOperationMetadata export_model_details = 22; + + // Details of ExportEvaluatedExamples operation. + ExportEvaluatedExamplesOperationMetadata export_evaluated_examples_details = 26; + } + + // Output only. Progress of operation. Range: [0, 100]. + // Not used currently. + int32 progress_percent = 13; + + // Output only. Partial failures encountered. + // E.g. single files that couldn't be read. + // This field should never exceed 20 entries. + // Status details field will contain standard GCP error details. + repeated google.rpc.Status partial_failures = 2; + + // Output only. Time when the operation was created. + google.protobuf.Timestamp create_time = 3; + + // Output only. Time when the operation was updated for the last time. + google.protobuf.Timestamp update_time = 4; +} + +// Details of operations that perform deletes of any entities. +message DeleteOperationMetadata { + +} + +// Details of DeployModel operation. +message DeployModelOperationMetadata { + +} + +// Details of UndeployModel operation. +message UndeployModelOperationMetadata { + +} + +// Details of CreateModel operation. +message CreateModelOperationMetadata { + +} + +// Details of ImportData operation. +message ImportDataOperationMetadata { + +} + +// Details of ExportData operation. +message ExportDataOperationMetadata { + // Further describes this export data's output. + // Supplements + // [OutputConfig][google.cloud.automl.v1beta1.OutputConfig]. + message ExportDataOutputInfo { + // The output location to which the exported data is written. + oneof output_location { + // The full path of the Google Cloud Storage directory created, into which + // the exported data is written. + string gcs_output_directory = 1; + + // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId + // format, into which the exported data is written. + string bigquery_output_dataset = 2; + } + } + + // Output only. Information further describing this export data's output. + ExportDataOutputInfo output_info = 1; +} + +// Details of BatchPredict operation. +message BatchPredictOperationMetadata { + // Further describes this batch predict's output. + // Supplements + // + // [BatchPredictOutputConfig][google.cloud.automl.v1beta1.BatchPredictOutputConfig]. + message BatchPredictOutputInfo { + // The output location into which prediction output is written. + oneof output_location { + // The full path of the Google Cloud Storage directory created, into which + // the prediction output is written. + string gcs_output_directory = 1; + + // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId + // format, into which the prediction output is written. + string bigquery_output_dataset = 2; + } + } + + // Output only. The input config that was given upon starting this + // batch predict operation. + BatchPredictInputConfig input_config = 1; + + // Output only. Information further describing this batch predict's output. + BatchPredictOutputInfo output_info = 2; +} + +// Details of ExportModel operation. +message ExportModelOperationMetadata { + // Further describes the output of model export. + // Supplements + // + // [ModelExportOutputConfig][google.cloud.automl.v1beta1.ModelExportOutputConfig]. + message ExportModelOutputInfo { + // The full path of the Google Cloud Storage directory created, into which + // the model will be exported. + string gcs_output_directory = 1; + } + + // Output only. Information further describing the output of this model + // export. + ExportModelOutputInfo output_info = 2; +} + +// Details of EvaluatedExamples operation. +message ExportEvaluatedExamplesOperationMetadata { + // Further describes the output of the evaluated examples export. + // Supplements + // + // [ExportEvaluatedExamplesOutputConfig][google.cloud.automl.v1beta1.ExportEvaluatedExamplesOutputConfig]. + message ExportEvaluatedExamplesOutputInfo { + // The path of the BigQuery dataset created, in bq://projectId.bqDatasetId + // format, into which the output of export evaluated examples is written. + string bigquery_output_dataset = 2; + } + + // Output only. Information further describing the output of this evaluated + // examples export. + ExportEvaluatedExamplesOutputInfo output_info = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/prediction_service.proto b/google/cloud/automl_v1beta1/proto/prediction_service.proto new file mode 100644 index 00000000..0bcf685e --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/prediction_service.proto @@ -0,0 +1,268 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/annotation_payload.proto"; +import "google/cloud/automl/v1beta1/data_items.proto"; +import "google/cloud/automl/v1beta1/io.proto"; +import "google/cloud/automl/v1beta1/operations.proto"; +import "google/longrunning/operations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "PredictionServiceProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// AutoML Prediction API. +// +// On any input that is documented to expect a string parameter in +// snake_case or kebab-case, either of those cases is accepted. +service PredictionService { + option (google.api.default_host) = "automl.googleapis.com"; + option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; + + // Perform an online prediction. The prediction result will be directly + // returned in the response. + // Available for following ML problems, and their expected request payloads: + // * Image Classification - Image in .JPEG, .GIF or .PNG format, image_bytes + // up to 30MB. + // * Image Object Detection - Image in .JPEG, .GIF or .PNG format, image_bytes + // up to 30MB. + // * Text Classification - TextSnippet, content up to 60,000 characters, + // UTF-8 encoded. + // * Text Extraction - TextSnippet, content up to 30,000 characters, + // UTF-8 NFC encoded. + // * Translation - TextSnippet, content up to 25,000 characters, UTF-8 + // encoded. + // * Tables - Row, with column values matching the columns of the model, + // up to 5MB. Not available for FORECASTING + // + // [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]. + // * Text Sentiment - TextSnippet, content up 500 characters, UTF-8 + // encoded. + rpc Predict(PredictRequest) returns (PredictResponse) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:predict" + body: "*" + }; + option (google.api.method_signature) = "name,payload,params"; + } + + // Perform a batch prediction. Unlike the online [Predict][google.cloud.automl.v1beta1.PredictionService.Predict], batch + // prediction result won't be immediately available in the response. Instead, + // a long running operation object is returned. User can poll the operation + // result via [GetOperation][google.longrunning.Operations.GetOperation] + // method. Once the operation is done, [BatchPredictResult][google.cloud.automl.v1beta1.BatchPredictResult] is returned in + // the [response][google.longrunning.Operation.response] field. + // Available for following ML problems: + // * Image Classification + // * Image Object Detection + // * Video Classification + // * Video Object Tracking * Text Extraction + // * Tables + rpc BatchPredict(BatchPredictRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:batchPredict" + body: "*" + }; + option (google.api.method_signature) = "name,input_config,output_config,params"; + option (google.longrunning.operation_info) = { + response_type: "BatchPredictResult" + metadata_type: "OperationMetadata" + }; + } +} + +// Request message for [PredictionService.Predict][google.cloud.automl.v1beta1.PredictionService.Predict]. +message PredictRequest { + // Required. Name of the model requested to serve the prediction. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // Required. Payload to perform a prediction on. The payload must match the + // problem type that the model was trained to solve. + ExamplePayload payload = 2 [(google.api.field_behavior) = REQUIRED]; + + // Additional domain-specific parameters, any string must be up to 25000 + // characters long. + // + // * For Image Classification: + // + // `score_threshold` - (float) A value from 0.0 to 1.0. When the model + // makes predictions for an image, it will only produce results that have + // at least this confidence score. The default is 0.5. + // + // * For Image Object Detection: + // `score_threshold` - (float) When Model detects objects on the image, + // it will only produce bounding boxes which have at least this + // confidence score. Value in 0 to 1 range, default is 0.5. + // `max_bounding_box_count` - (int64) No more than this number of bounding + // boxes will be returned in the response. Default is 100, the + // requested value may be limited by server. + // * For Tables: + // feature_importance - (boolean) Whether feature importance + // should be populated in the returned TablesAnnotation. + // The default is false. + map params = 3; +} + +// Response message for [PredictionService.Predict][google.cloud.automl.v1beta1.PredictionService.Predict]. +message PredictResponse { + // Prediction result. + // Translation and Text Sentiment will return precisely one payload. + repeated AnnotationPayload payload = 1; + + // The preprocessed example that AutoML actually makes prediction on. + // Empty if AutoML does not preprocess the input example. + // * For Text Extraction: + // If the input is a .pdf file, the OCR'ed text will be provided in + // [document_text][google.cloud.automl.v1beta1.Document.document_text]. + ExamplePayload preprocessed_input = 3; + + // Additional domain-specific prediction response metadata. + // + // * For Image Object Detection: + // `max_bounding_box_count` - (int64) At most that many bounding boxes per + // image could have been returned. + // + // * For Text Sentiment: + // `sentiment_score` - (float, deprecated) A value between -1 and 1, + // -1 maps to least positive sentiment, while 1 maps to the most positive + // one and the higher the score, the more positive the sentiment in the + // document is. Yet these values are relative to the training data, so + // e.g. if all data was positive then -1 will be also positive (though + // the least). + // The sentiment_score shouldn't be confused with "score" or "magnitude" + // from the previous Natural Language Sentiment Analysis API. + map metadata = 2; +} + +// Request message for [PredictionService.BatchPredict][google.cloud.automl.v1beta1.PredictionService.BatchPredict]. +message BatchPredictRequest { + // Required. Name of the model requested to serve the batch prediction. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // Required. The input configuration for batch prediction. + BatchPredictInputConfig input_config = 3 [(google.api.field_behavior) = REQUIRED]; + + // Required. The Configuration specifying where output predictions should + // be written. + BatchPredictOutputConfig output_config = 4 [(google.api.field_behavior) = REQUIRED]; + + // Required. Additional domain-specific parameters for the predictions, any string must + // be up to 25000 characters long. + // + // * For Text Classification: + // + // `score_threshold` - (float) A value from 0.0 to 1.0. When the model + // makes predictions for a text snippet, it will only produce results + // that have at least this confidence score. The default is 0.5. + // + // * For Image Classification: + // + // `score_threshold` - (float) A value from 0.0 to 1.0. When the model + // makes predictions for an image, it will only produce results that + // have at least this confidence score. The default is 0.5. + // + // * For Image Object Detection: + // + // `score_threshold` - (float) When Model detects objects on the image, + // it will only produce bounding boxes which have at least this + // confidence score. Value in 0 to 1 range, default is 0.5. + // `max_bounding_box_count` - (int64) No more than this number of bounding + // boxes will be produced per image. Default is 100, the + // requested value may be limited by server. + // + // * For Video Classification : + // + // `score_threshold` - (float) A value from 0.0 to 1.0. When the model + // makes predictions for a video, it will only produce results that + // have at least this confidence score. The default is 0.5. + // `segment_classification` - (boolean) Set to true to request + // segment-level classification. AutoML Video Intelligence returns + // labels and their confidence scores for the entire segment of the + // video that user specified in the request configuration. + // The default is "true". + // `shot_classification` - (boolean) Set to true to request shot-level + // classification. AutoML Video Intelligence determines the boundaries + // for each camera shot in the entire segment of the video that user + // specified in the request configuration. AutoML Video Intelligence + // then returns labels and their confidence scores for each detected + // shot, along with the start and end time of the shot. + // WARNING: Model evaluation is not done for this classification type, + // the quality of it depends on training data, but there are no metrics + // provided to describe that quality. The default is "false". + // `1s_interval_classification` - (boolean) Set to true to request + // classification for a video at one-second intervals. AutoML Video + // Intelligence returns labels and their confidence scores for each + // second of the entire segment of the video that user specified in the + // request configuration. + // WARNING: Model evaluation is not done for this classification + // type, the quality of it depends on training data, but there are no + // metrics provided to describe that quality. The default is + // "false". + // + // * For Tables: + // + // feature_importance - (boolean) Whether feature importance + // should be populated in the returned TablesAnnotations. The + // default is false. + // + // * For Video Object Tracking: + // + // `score_threshold` - (float) When Model detects objects on video frames, + // it will only produce bounding boxes which have at least this + // confidence score. Value in 0 to 1 range, default is 0.5. + // `max_bounding_box_count` - (int64) No more than this number of bounding + // boxes will be returned per frame. Default is 100, the requested + // value may be limited by server. + // `min_bounding_box_size` - (float) Only bounding boxes with shortest edge + // at least that long as a relative value of video frame size will be + // returned. Value in 0 to 1 range. Default is 0. + map params = 5 [(google.api.field_behavior) = REQUIRED]; +} + +// Result of the Batch Predict. This message is returned in +// [response][google.longrunning.Operation.response] of the operation returned +// by the [PredictionService.BatchPredict][google.cloud.automl.v1beta1.PredictionService.BatchPredict]. +message BatchPredictResult { + // Additional domain-specific prediction response metadata. + // + // * For Image Object Detection: + // `max_bounding_box_count` - (int64) At most that many bounding boxes per + // image could have been returned. + // + // * For Video Object Tracking: + // `max_bounding_box_count` - (int64) At most that many bounding boxes per + // frame could have been returned. + map metadata = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/ranges.proto b/google/cloud/automl_v1beta1/proto/ranges.proto new file mode 100644 index 00000000..89572bb0 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/ranges.proto @@ -0,0 +1,35 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "RangesProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A range between two double numbers. +message DoubleRange { + // Start of the range, inclusive. + double start = 1; + + // End of the range, exclusive. + double end = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/regression.proto b/google/cloud/automl_v1beta1/proto/regression.proto new file mode 100644 index 00000000..1286d3d8 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/regression.proto @@ -0,0 +1,44 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_outer_classname = "RegressionProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Metrics for regression problems. +message RegressionEvaluationMetrics { + // Output only. Root Mean Squared Error (RMSE). + float root_mean_squared_error = 1; + + // Output only. Mean Absolute Error (MAE). + float mean_absolute_error = 2; + + // Output only. Mean absolute percentage error. Only set if all ground truth + // values are are positive. + float mean_absolute_percentage_error = 3; + + // Output only. R squared. + float r_squared = 4; + + // Output only. Root mean squared log error. + float root_mean_squared_log_error = 5; +} diff --git a/google/cloud/automl_v1beta1/proto/service.proto b/google/cloud/automl_v1beta1/proto/service.proto new file mode 100644 index 00000000..a421ece1 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/service.proto @@ -0,0 +1,800 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/annotation_payload.proto"; +import "google/cloud/automl/v1beta1/annotation_spec.proto"; +import "google/cloud/automl/v1beta1/column_spec.proto"; +import "google/cloud/automl/v1beta1/dataset.proto"; +import "google/cloud/automl/v1beta1/image.proto"; +import "google/cloud/automl/v1beta1/io.proto"; +import "google/cloud/automl/v1beta1/model.proto"; +import "google/cloud/automl/v1beta1/model_evaluation.proto"; +import "google/cloud/automl/v1beta1/operations.proto"; +import "google/cloud/automl/v1beta1/table_spec.proto"; +import "google/longrunning/operations.proto"; +import "google/protobuf/field_mask.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "AutoMlProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// AutoML Server API. +// +// The resource names are assigned by the server. +// The server never reuses names that it has created after the resources with +// those names are deleted. +// +// An ID of a resource is the last element of the item's resource name. For +// `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}`, then +// the id for the item is `{dataset_id}`. +// +// Currently the only supported `location_id` is "us-central1". +// +// On any input that is documented to expect a string parameter in +// snake_case or kebab-case, either of those cases is accepted. +service AutoMl { + option (google.api.default_host) = "automl.googleapis.com"; + option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; + + // Creates a dataset. + rpc CreateDataset(CreateDatasetRequest) returns (Dataset) { + option (google.api.http) = { + post: "/v1beta1/{parent=projects/*/locations/*}/datasets" + body: "dataset" + }; + option (google.api.method_signature) = "parent,dataset"; + } + + // Gets a dataset. + rpc GetDataset(GetDatasetRequest) returns (Dataset) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/datasets/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists datasets in a project. + rpc ListDatasets(ListDatasetsRequest) returns (ListDatasetsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*}/datasets" + }; + option (google.api.method_signature) = "parent"; + } + + // Updates a dataset. + rpc UpdateDataset(UpdateDatasetRequest) returns (Dataset) { + option (google.api.http) = { + patch: "/v1beta1/{dataset.name=projects/*/locations/*/datasets/*}" + body: "dataset" + }; + option (google.api.method_signature) = "dataset"; + } + + // Deletes a dataset and all of its contents. + // Returns empty response in the + // [response][google.longrunning.Operation.response] field when it completes, + // and `delete_details` in the + // [metadata][google.longrunning.Operation.metadata] field. + rpc DeleteDataset(DeleteDatasetRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + delete: "/v1beta1/{name=projects/*/locations/*/datasets/*}" + }; + option (google.api.method_signature) = "name"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Imports data into a dataset. + // For Tables this method can only be called on an empty Dataset. + // + // For Tables: + // * A + // [schema_inference_version][google.cloud.automl.v1beta1.InputConfig.params] + // parameter must be explicitly set. + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc ImportData(ImportDataRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/datasets/*}:importData" + body: "*" + }; + option (google.api.method_signature) = "name,input_config"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Exports dataset's data to the provided output location. + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc ExportData(ExportDataRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/datasets/*}:exportData" + body: "*" + }; + option (google.api.method_signature) = "name,output_config"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Gets an annotation spec. + rpc GetAnnotationSpec(GetAnnotationSpecRequest) returns (AnnotationSpec) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/datasets/*/annotationSpecs/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Gets a table spec. + rpc GetTableSpec(GetTableSpecRequest) returns (TableSpec) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/datasets/*/tableSpecs/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists table specs in a dataset. + rpc ListTableSpecs(ListTableSpecsRequest) returns (ListTableSpecsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*/datasets/*}/tableSpecs" + }; + option (google.api.method_signature) = "parent"; + } + + // Updates a table spec. + rpc UpdateTableSpec(UpdateTableSpecRequest) returns (TableSpec) { + option (google.api.http) = { + patch: "/v1beta1/{table_spec.name=projects/*/locations/*/datasets/*/tableSpecs/*}" + body: "table_spec" + }; + option (google.api.method_signature) = "table_spec"; + } + + // Gets a column spec. + rpc GetColumnSpec(GetColumnSpecRequest) returns (ColumnSpec) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/datasets/*/tableSpecs/*/columnSpecs/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists column specs in a table spec. + rpc ListColumnSpecs(ListColumnSpecsRequest) returns (ListColumnSpecsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*/datasets/*/tableSpecs/*}/columnSpecs" + }; + option (google.api.method_signature) = "parent"; + } + + // Updates a column spec. + rpc UpdateColumnSpec(UpdateColumnSpecRequest) returns (ColumnSpec) { + option (google.api.http) = { + patch: "/v1beta1/{column_spec.name=projects/*/locations/*/datasets/*/tableSpecs/*/columnSpecs/*}" + body: "column_spec" + }; + option (google.api.method_signature) = "column_spec"; + } + + // Creates a model. + // Returns a Model in the [response][google.longrunning.Operation.response] + // field when it completes. + // When you create a model, several model evaluations are created for it: + // a global evaluation, and one evaluation for each annotation spec. + rpc CreateModel(CreateModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{parent=projects/*/locations/*}/models" + body: "model" + }; + option (google.api.method_signature) = "parent,model"; + option (google.longrunning.operation_info) = { + response_type: "Model" + metadata_type: "OperationMetadata" + }; + } + + // Gets a model. + rpc GetModel(GetModelRequest) returns (Model) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/models/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists models. + rpc ListModels(ListModelsRequest) returns (ListModelsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*}/models" + }; + option (google.api.method_signature) = "parent"; + } + + // Deletes a model. + // Returns `google.protobuf.Empty` in the + // [response][google.longrunning.Operation.response] field when it completes, + // and `delete_details` in the + // [metadata][google.longrunning.Operation.metadata] field. + rpc DeleteModel(DeleteModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + delete: "/v1beta1/{name=projects/*/locations/*/models/*}" + }; + option (google.api.method_signature) = "name"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Deploys a model. If a model is already deployed, deploying it with the + // same parameters has no effect. Deploying with different parametrs + // (as e.g. changing + // + // [node_number][google.cloud.automl.v1beta1.ImageObjectDetectionModelDeploymentMetadata.node_number]) + // will reset the deployment state without pausing the model's availability. + // + // Only applicable for Text Classification, Image Object Detection , Tables, and Image Segmentation; all other domains manage + // deployment automatically. + // + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc DeployModel(DeployModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:deploy" + body: "*" + }; + option (google.api.method_signature) = "name"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Undeploys a model. If the model is not deployed this method has no effect. + // + // Only applicable for Text Classification, Image Object Detection and Tables; + // all other domains manage deployment automatically. + // + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc UndeployModel(UndeployModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:undeploy" + body: "*" + }; + option (google.api.method_signature) = "name"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Exports a trained, "export-able", model to a user specified Google Cloud + // Storage location. A model is considered export-able if and only if it has + // an export format defined for it in + // + // [ModelExportOutputConfig][google.cloud.automl.v1beta1.ModelExportOutputConfig]. + // + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc ExportModel(ExportModelRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:export" + body: "*" + }; + option (google.api.method_signature) = "name,output_config"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Exports examples on which the model was evaluated (i.e. which were in the + // TEST set of the dataset the model was created from), together with their + // ground truth annotations and the annotations created (predicted) by the + // model. + // The examples, ground truth and predictions are exported in the state + // they were at the moment the model was evaluated. + // + // This export is available only for 30 days since the model evaluation is + // created. + // + // Currently only available for Tables. + // + // Returns an empty response in the + // [response][google.longrunning.Operation.response] field when it completes. + rpc ExportEvaluatedExamples(ExportEvaluatedExamplesRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1beta1/{name=projects/*/locations/*/models/*}:exportEvaluatedExamples" + body: "*" + }; + option (google.api.method_signature) = "name,output_config"; + option (google.longrunning.operation_info) = { + response_type: "google.protobuf.Empty" + metadata_type: "OperationMetadata" + }; + } + + // Gets a model evaluation. + rpc GetModelEvaluation(GetModelEvaluationRequest) returns (ModelEvaluation) { + option (google.api.http) = { + get: "/v1beta1/{name=projects/*/locations/*/models/*/modelEvaluations/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists model evaluations. + rpc ListModelEvaluations(ListModelEvaluationsRequest) returns (ListModelEvaluationsResponse) { + option (google.api.http) = { + get: "/v1beta1/{parent=projects/*/locations/*/models/*}/modelEvaluations" + }; + option (google.api.method_signature) = "parent"; + } +} + +// Request message for [AutoMl.CreateDataset][google.cloud.automl.v1beta1.AutoMl.CreateDataset]. +message CreateDatasetRequest { + // Required. The resource name of the project to create the dataset for. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "locations.googleapis.com/Location" + } + ]; + + // Required. The dataset to create. + Dataset dataset = 2 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.GetDataset][google.cloud.automl.v1beta1.AutoMl.GetDataset]. +message GetDatasetRequest { + // Required. The resource name of the dataset to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; +} + +// Request message for [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets]. +message ListDatasetsRequest { + // Required. The resource name of the project from which to list datasets. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "locations.googleapis.com/Location" + } + ]; + + // An expression for filtering the results of the request. + // + // * `dataset_metadata` - for existence of the case (e.g. + // image_classification_dataset_metadata:*). Some examples of using the filter are: + // + // * `translation_dataset_metadata:*` --> The dataset has + // translation_dataset_metadata. + string filter = 3; + + // Requested page size. Server may return fewer results than requested. + // If unspecified, server will pick a default size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return + // Typically obtained via + // [ListDatasetsResponse.next_page_token][google.cloud.automl.v1beta1.ListDatasetsResponse.next_page_token] of the previous + // [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListDatasets][google.cloud.automl.v1beta1.AutoMl.ListDatasets]. +message ListDatasetsResponse { + // The datasets read. + repeated Dataset datasets = 1; + + // A token to retrieve next page of results. + // Pass to [ListDatasetsRequest.page_token][google.cloud.automl.v1beta1.ListDatasetsRequest.page_token] to obtain that page. + string next_page_token = 2; +} + +// Request message for [AutoMl.UpdateDataset][google.cloud.automl.v1beta1.AutoMl.UpdateDataset] +message UpdateDatasetRequest { + // Required. The dataset which replaces the resource on the server. + Dataset dataset = 1 [(google.api.field_behavior) = REQUIRED]; + + // The update mask applies to the resource. + google.protobuf.FieldMask update_mask = 2; +} + +// Request message for [AutoMl.DeleteDataset][google.cloud.automl.v1beta1.AutoMl.DeleteDataset]. +message DeleteDatasetRequest { + // Required. The resource name of the dataset to delete. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; +} + +// Request message for [AutoMl.ImportData][google.cloud.automl.v1beta1.AutoMl.ImportData]. +message ImportDataRequest { + // Required. Dataset name. Dataset must already exist. All imported + // annotations and examples will be added. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; + + // Required. The desired input location and its domain specific semantics, + // if any. + InputConfig input_config = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.ExportData][google.cloud.automl.v1beta1.AutoMl.ExportData]. +message ExportDataRequest { + // Required. The resource name of the dataset. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; + + // Required. The desired output location. + OutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.GetAnnotationSpec][google.cloud.automl.v1beta1.AutoMl.GetAnnotationSpec]. +message GetAnnotationSpecRequest { + // Required. The resource name of the annotation spec to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/AnnotationSpec" + } + ]; +} + +// Request message for [AutoMl.GetTableSpec][google.cloud.automl.v1beta1.AutoMl.GetTableSpec]. +message GetTableSpecRequest { + // Required. The resource name of the table spec to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/TableSpec" + } + ]; + + // Mask specifying which fields to read. + google.protobuf.FieldMask field_mask = 2; +} + +// Request message for [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs]. +message ListTableSpecsRequest { + // Required. The resource name of the dataset to list table specs from. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Dataset" + } + ]; + + // Mask specifying which fields to read. + google.protobuf.FieldMask field_mask = 2; + + // Filter expression, see go/filtering. + string filter = 3; + + // Requested page size. The server can return fewer results than requested. + // If unspecified, the server will pick a default size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return. + // Typically obtained from the + // [ListTableSpecsResponse.next_page_token][google.cloud.automl.v1beta1.ListTableSpecsResponse.next_page_token] field of the previous + // [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListTableSpecs][google.cloud.automl.v1beta1.AutoMl.ListTableSpecs]. +message ListTableSpecsResponse { + // The table specs read. + repeated TableSpec table_specs = 1; + + // A token to retrieve next page of results. + // Pass to [ListTableSpecsRequest.page_token][google.cloud.automl.v1beta1.ListTableSpecsRequest.page_token] to obtain that page. + string next_page_token = 2; +} + +// Request message for [AutoMl.UpdateTableSpec][google.cloud.automl.v1beta1.AutoMl.UpdateTableSpec] +message UpdateTableSpecRequest { + // Required. The table spec which replaces the resource on the server. + TableSpec table_spec = 1 [(google.api.field_behavior) = REQUIRED]; + + // The update mask applies to the resource. + google.protobuf.FieldMask update_mask = 2; +} + +// Request message for [AutoMl.GetColumnSpec][google.cloud.automl.v1beta1.AutoMl.GetColumnSpec]. +message GetColumnSpecRequest { + // Required. The resource name of the column spec to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/ColumnSpec" + } + ]; + + // Mask specifying which fields to read. + google.protobuf.FieldMask field_mask = 2; +} + +// Request message for [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs]. +message ListColumnSpecsRequest { + // Required. The resource name of the table spec to list column specs from. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/TableSpec" + } + ]; + + // Mask specifying which fields to read. + google.protobuf.FieldMask field_mask = 2; + + // Filter expression, see go/filtering. + string filter = 3; + + // Requested page size. The server can return fewer results than requested. + // If unspecified, the server will pick a default size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return. + // Typically obtained from the + // [ListColumnSpecsResponse.next_page_token][google.cloud.automl.v1beta1.ListColumnSpecsResponse.next_page_token] field of the previous + // [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListColumnSpecs][google.cloud.automl.v1beta1.AutoMl.ListColumnSpecs]. +message ListColumnSpecsResponse { + // The column specs read. + repeated ColumnSpec column_specs = 1; + + // A token to retrieve next page of results. + // Pass to [ListColumnSpecsRequest.page_token][google.cloud.automl.v1beta1.ListColumnSpecsRequest.page_token] to obtain that page. + string next_page_token = 2; +} + +// Request message for [AutoMl.UpdateColumnSpec][google.cloud.automl.v1beta1.AutoMl.UpdateColumnSpec] +message UpdateColumnSpecRequest { + // Required. The column spec which replaces the resource on the server. + ColumnSpec column_spec = 1 [(google.api.field_behavior) = REQUIRED]; + + // The update mask applies to the resource. + google.protobuf.FieldMask update_mask = 2; +} + +// Request message for [AutoMl.CreateModel][google.cloud.automl.v1beta1.AutoMl.CreateModel]. +message CreateModelRequest { + // Required. Resource name of the parent project where the model is being created. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "locations.googleapis.com/Location" + } + ]; + + // Required. The model to create. + Model model = 4 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.GetModel][google.cloud.automl.v1beta1.AutoMl.GetModel]. +message GetModelRequest { + // Required. Resource name of the model. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; +} + +// Request message for [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels]. +message ListModelsRequest { + // Required. Resource name of the project, from which to list the models. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "locations.googleapis.com/Location" + } + ]; + + // An expression for filtering the results of the request. + // + // * `model_metadata` - for existence of the case (e.g. + // video_classification_model_metadata:*). + // * `dataset_id` - for = or !=. Some examples of using the filter are: + // + // * `image_classification_model_metadata:*` --> The model has + // image_classification_model_metadata. + // * `dataset_id=5` --> The model was created from a dataset with ID 5. + string filter = 3; + + // Requested page size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return + // Typically obtained via + // [ListModelsResponse.next_page_token][google.cloud.automl.v1beta1.ListModelsResponse.next_page_token] of the previous + // [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListModels][google.cloud.automl.v1beta1.AutoMl.ListModels]. +message ListModelsResponse { + // List of models in the requested page. + repeated Model model = 1; + + // A token to retrieve next page of results. + // Pass to [ListModelsRequest.page_token][google.cloud.automl.v1beta1.ListModelsRequest.page_token] to obtain that page. + string next_page_token = 2; +} + +// Request message for [AutoMl.DeleteModel][google.cloud.automl.v1beta1.AutoMl.DeleteModel]. +message DeleteModelRequest { + // Required. Resource name of the model being deleted. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; +} + +// Request message for [AutoMl.DeployModel][google.cloud.automl.v1beta1.AutoMl.DeployModel]. +message DeployModelRequest { + // The per-domain specific deployment parameters. + oneof model_deployment_metadata { + // Model deployment metadata specific to Image Object Detection. + ImageObjectDetectionModelDeploymentMetadata image_object_detection_model_deployment_metadata = 2; + + // Model deployment metadata specific to Image Classification. + ImageClassificationModelDeploymentMetadata image_classification_model_deployment_metadata = 4; + } + + // Required. Resource name of the model to deploy. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; +} + +// Request message for [AutoMl.UndeployModel][google.cloud.automl.v1beta1.AutoMl.UndeployModel]. +message UndeployModelRequest { + // Required. Resource name of the model to undeploy. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; +} + +// Request message for [AutoMl.ExportModel][google.cloud.automl.v1beta1.AutoMl.ExportModel]. +// Models need to be enabled for exporting, otherwise an error code will be +// returned. +message ExportModelRequest { + // Required. The resource name of the model to export. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // Required. The desired output location and configuration. + ModelExportOutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.ExportEvaluatedExamples][google.cloud.automl.v1beta1.AutoMl.ExportEvaluatedExamples]. +message ExportEvaluatedExamplesRequest { + // Required. The resource name of the model whose evaluated examples are to + // be exported. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // Required. The desired output location and configuration. + ExportEvaluatedExamplesOutputConfig output_config = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Request message for [AutoMl.GetModelEvaluation][google.cloud.automl.v1beta1.AutoMl.GetModelEvaluation]. +message GetModelEvaluationRequest { + // Required. Resource name for the model evaluation. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/ModelEvaluation" + } + ]; +} + +// Request message for [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations]. +message ListModelEvaluationsRequest { + // Required. Resource name of the model to list the model evaluations for. + // If modelId is set as "-", this will list model evaluations from across all + // models of the parent location. + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "automl.googleapis.com/Model" + } + ]; + + // An expression for filtering the results of the request. + // + // * `annotation_spec_id` - for =, != or existence. See example below for + // the last. + // + // Some examples of using the filter are: + // + // * `annotation_spec_id!=4` --> The model evaluation was done for + // annotation spec with ID different than 4. + // * `NOT annotation_spec_id:*` --> The model evaluation was done for + // aggregate of all annotation specs. + string filter = 3; + + // Requested page size. + int32 page_size = 4; + + // A token identifying a page of results for the server to return. + // Typically obtained via + // [ListModelEvaluationsResponse.next_page_token][google.cloud.automl.v1beta1.ListModelEvaluationsResponse.next_page_token] of the previous + // [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations] call. + string page_token = 6; +} + +// Response message for [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations]. +message ListModelEvaluationsResponse { + // List of model evaluations in the requested page. + repeated ModelEvaluation model_evaluation = 1; + + // A token to retrieve next page of results. + // Pass to the [ListModelEvaluationsRequest.page_token][google.cloud.automl.v1beta1.ListModelEvaluationsRequest.page_token] field of a new + // [AutoMl.ListModelEvaluations][google.cloud.automl.v1beta1.AutoMl.ListModelEvaluations] request to obtain that page. + string next_page_token = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/table_spec.proto b/google/cloud/automl_v1beta1/proto/table_spec.proto new file mode 100644 index 00000000..bc3fc744 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/table_spec.proto @@ -0,0 +1,78 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/resource.proto"; +import "google/cloud/automl/v1beta1/io.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A specification of a relational table. +// The table's schema is represented via its child column specs. It is +// pre-populated as part of ImportData by schema inference algorithm, the +// version of which is a required parameter of ImportData InputConfig. +// Note: While working with a table, at times the schema may be +// inconsistent with the data in the table (e.g. string in a FLOAT64 column). +// The consistency validation is done upon creation of a model. +// Used by: +// * Tables +message TableSpec { + option (google.api.resource) = { + type: "automl.googleapis.com/TableSpec" + pattern: "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}" + }; + + // Output only. The resource name of the table spec. + // Form: + // + // `projects/{project_id}/locations/{location_id}/datasets/{dataset_id}/tableSpecs/{table_spec_id}` + string name = 1; + + // column_spec_id of the time column. Only used if the parent dataset's + // ml_use_column_spec_id is not set. Used to split rows into TRAIN, VALIDATE + // and TEST sets such that oldest rows go to TRAIN set, newest to TEST, and + // those in between to VALIDATE. + // Required type: TIMESTAMP. + // If both this column and ml_use_column are not set, then ML use of all rows + // will be assigned by AutoML. NOTE: Updates of this field will instantly + // affect any other users concurrently working with the dataset. + string time_column_spec_id = 2; + + // Output only. The number of rows (i.e. examples) in the table. + int64 row_count = 3; + + // Output only. The number of valid rows (i.e. without values that don't match + // DataType-s of their columns). + int64 valid_row_count = 4; + + // Output only. The number of columns of the table. That is, the number of + // child ColumnSpec-s. + int64 column_count = 7; + + // Output only. Input configs via which data currently residing in the table + // had been imported. + repeated InputConfig input_configs = 5; + + // Used to perform consistent read-modify-write updates. If not set, a blind + // "overwrite" update happens. + string etag = 6; +} diff --git a/google/cloud/automl_v1beta1/proto/tables.proto b/google/cloud/automl_v1beta1/proto/tables.proto new file mode 100644 index 00000000..5327f5e7 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/tables.proto @@ -0,0 +1,292 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/cloud/automl/v1beta1/column_spec.proto"; +import "google/cloud/automl/v1beta1/data_items.proto"; +import "google/cloud/automl/v1beta1/data_stats.proto"; +import "google/cloud/automl/v1beta1/ranges.proto"; +import "google/cloud/automl/v1beta1/regression.proto"; +import "google/cloud/automl/v1beta1/temporal.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Metadata for a dataset used for AutoML Tables. +message TablesDatasetMetadata { + // Output only. The table_spec_id of the primary table of this dataset. + string primary_table_spec_id = 1; + + // column_spec_id of the primary table's column that should be used as the + // training & prediction target. + // This column must be non-nullable and have one of following data types + // (otherwise model creation will error): + // + // * CATEGORY + // + // * FLOAT64 + // + // If the type is CATEGORY , only up to + // 100 unique values may exist in that column across all rows. + // + // NOTE: Updates of this field will instantly affect any other users + // concurrently working with the dataset. + string target_column_spec_id = 2; + + // column_spec_id of the primary table's column that should be used as the + // weight column, i.e. the higher the value the more important the row will be + // during model training. + // Required type: FLOAT64. + // Allowed values: 0 to 10000, inclusive on both ends; 0 means the row is + // ignored for training. + // If not set all rows are assumed to have equal weight of 1. + // NOTE: Updates of this field will instantly affect any other users + // concurrently working with the dataset. + string weight_column_spec_id = 3; + + // column_spec_id of the primary table column which specifies a possible ML + // use of the row, i.e. the column will be used to split the rows into TRAIN, + // VALIDATE and TEST sets. + // Required type: STRING. + // This column, if set, must either have all of `TRAIN`, `VALIDATE`, `TEST` + // among its values, or only have `TEST`, `UNASSIGNED` values. In the latter + // case the rows with `UNASSIGNED` value will be assigned by AutoML. Note + // that if a given ml use distribution makes it impossible to create a "good" + // model, that call will error describing the issue. + // If both this column_spec_id and primary table's time_column_spec_id are not + // set, then all rows are treated as `UNASSIGNED`. + // NOTE: Updates of this field will instantly affect any other users + // concurrently working with the dataset. + string ml_use_column_spec_id = 4; + + // Output only. Correlations between + // + // [TablesDatasetMetadata.target_column_spec_id][google.cloud.automl.v1beta1.TablesDatasetMetadata.target_column_spec_id], + // and other columns of the + // + // [TablesDatasetMetadataprimary_table][google.cloud.automl.v1beta1.TablesDatasetMetadata.primary_table_spec_id]. + // Only set if the target column is set. Mapping from other column spec id to + // its CorrelationStats with the target column. + // This field may be stale, see the stats_update_time field for + // for the timestamp at which these stats were last updated. + map target_column_correlations = 6; + + // Output only. The most recent timestamp when target_column_correlations + // field and all descendant ColumnSpec.data_stats and + // ColumnSpec.top_correlated_columns fields were last (re-)generated. Any + // changes that happened to the dataset afterwards are not reflected in these + // fields values. The regeneration happens in the background on a best effort + // basis. + google.protobuf.Timestamp stats_update_time = 7; +} + +// Model metadata specific to AutoML Tables. +message TablesModelMetadata { + // Additional optimization objective configuration. Required for + // `MAXIMIZE_PRECISION_AT_RECALL` and `MAXIMIZE_RECALL_AT_PRECISION`, + // otherwise unused. + oneof additional_optimization_objective_config { + // Required when optimization_objective is "MAXIMIZE_PRECISION_AT_RECALL". + // Must be between 0 and 1, inclusive. + float optimization_objective_recall_value = 17; + + // Required when optimization_objective is "MAXIMIZE_RECALL_AT_PRECISION". + // Must be between 0 and 1, inclusive. + float optimization_objective_precision_value = 18; + } + + // Column spec of the dataset's primary table's column the model is + // predicting. Snapshotted when model creation started. + // Only 3 fields are used: + // name - May be set on CreateModel, if it's not then the ColumnSpec + // corresponding to the current target_column_spec_id of the dataset + // the model is trained from is used. + // If neither is set, CreateModel will error. + // display_name - Output only. + // data_type - Output only. + ColumnSpec target_column_spec = 2; + + // Column specs of the dataset's primary table's columns, on which + // the model is trained and which are used as the input for predictions. + // The + // + // [target_column][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] + // as well as, according to dataset's state upon model creation, + // + // [weight_column][google.cloud.automl.v1beta1.TablesDatasetMetadata.weight_column_spec_id], + // and + // + // [ml_use_column][google.cloud.automl.v1beta1.TablesDatasetMetadata.ml_use_column_spec_id] + // must never be included here. + // + // Only 3 fields are used: + // + // * name - May be set on CreateModel, if set only the columns specified are + // used, otherwise all primary table's columns (except the ones listed + // above) are used for the training and prediction input. + // + // * display_name - Output only. + // + // * data_type - Output only. + repeated ColumnSpec input_feature_column_specs = 3; + + // Objective function the model is optimizing towards. The training process + // creates a model that maximizes/minimizes the value of the objective + // function over the validation set. + // + // The supported optimization objectives depend on the prediction type. + // If the field is not set, a default objective function is used. + // + // CLASSIFICATION_BINARY: + // "MAXIMIZE_AU_ROC" (default) - Maximize the area under the receiver + // operating characteristic (ROC) curve. + // "MINIMIZE_LOG_LOSS" - Minimize log loss. + // "MAXIMIZE_AU_PRC" - Maximize the area under the precision-recall curve. + // "MAXIMIZE_PRECISION_AT_RECALL" - Maximize precision for a specified + // recall value. + // "MAXIMIZE_RECALL_AT_PRECISION" - Maximize recall for a specified + // precision value. + // + // CLASSIFICATION_MULTI_CLASS : + // "MINIMIZE_LOG_LOSS" (default) - Minimize log loss. + // + // + // REGRESSION: + // "MINIMIZE_RMSE" (default) - Minimize root-mean-squared error (RMSE). + // "MINIMIZE_MAE" - Minimize mean-absolute error (MAE). + // "MINIMIZE_RMSLE" - Minimize root-mean-squared log error (RMSLE). + string optimization_objective = 4; + + // Output only. Auxiliary information for each of the + // input_feature_column_specs with respect to this particular model. + repeated TablesModelColumnInfo tables_model_column_info = 5; + + // Required. The train budget of creating this model, expressed in milli node + // hours i.e. 1,000 value in this field means 1 node hour. + // + // The training cost of the model will not exceed this budget. The final cost + // will be attempted to be close to the budget, though may end up being (even) + // noticeably smaller - at the backend's discretion. This especially may + // happen when further model training ceases to provide any improvements. + // + // If the budget is set to a value known to be insufficient to train a + // model for the given dataset, the training won't be attempted and + // will error. + // + // The train budget must be between 1,000 and 72,000 milli node hours, + // inclusive. + int64 train_budget_milli_node_hours = 6; + + // Output only. The actual training cost of the model, expressed in milli + // node hours, i.e. 1,000 value in this field means 1 node hour. Guaranteed + // to not exceed the train budget. + int64 train_cost_milli_node_hours = 7; + + // Use the entire training budget. This disables the early stopping feature. + // By default, the early stopping feature is enabled, which means that AutoML + // Tables might stop training before the entire training budget has been used. + bool disable_early_stopping = 12; +} + +// Contains annotation details specific to Tables. +message TablesAnnotation { + // Output only. A confidence estimate between 0.0 and 1.0, inclusive. A higher + // value means greater confidence in the returned value. + // For + // + // [target_column_spec][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] + // of FLOAT64 data type the score is not populated. + float score = 1; + + // Output only. Only populated when + // + // [target_column_spec][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec] + // has FLOAT64 data type. An interval in which the exactly correct target + // value has 95% chance to be in. + DoubleRange prediction_interval = 4; + + // The predicted value of the row's + // + // [target_column][google.cloud.automl.v1beta1.TablesModelMetadata.target_column_spec]. + // The value depends on the column's DataType: + // + // * CATEGORY - the predicted (with the above confidence `score`) CATEGORY + // value. + // + // * FLOAT64 - the predicted (with above `prediction_interval`) FLOAT64 value. + google.protobuf.Value value = 2; + + // Output only. Auxiliary information for each of the model's + // + // [input_feature_column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs] + // with respect to this particular prediction. + // If no other fields than + // + // [column_spec_name][google.cloud.automl.v1beta1.TablesModelColumnInfo.column_spec_name] + // and + // + // [column_display_name][google.cloud.automl.v1beta1.TablesModelColumnInfo.column_display_name] + // would be populated, then this whole field is not. + repeated TablesModelColumnInfo tables_model_column_info = 3; + + // Output only. Stores the prediction score for the baseline example, which + // is defined as the example with all values set to their baseline values. + // This is used as part of the Sampled Shapley explanation of the model's + // prediction. This field is populated only when feature importance is + // requested. For regression models, this holds the baseline prediction for + // the baseline example. For classification models, this holds the baseline + // prediction for the baseline example for the argmax class. + float baseline_score = 5; +} + +// An information specific to given column and Tables Model, in context +// of the Model and the predictions created by it. +message TablesModelColumnInfo { + // Output only. The name of the ColumnSpec describing the column. Not + // populated when this proto is outputted to BigQuery. + string column_spec_name = 1; + + // Output only. The display name of the column (same as the display_name of + // its ColumnSpec). + string column_display_name = 2; + + // Output only. When given as part of a Model (always populated): + // Measurement of how much model predictions correctness on the TEST data + // depend on values in this column. A value between 0 and 1, higher means + // higher influence. These values are normalized - for all input feature + // columns of a given model they add to 1. + // + // When given back by Predict (populated iff + // [feature_importance + // param][google.cloud.automl.v1beta1.PredictRequest.params] is set) or Batch + // Predict (populated iff + // [feature_importance][google.cloud.automl.v1beta1.PredictRequest.params] + // param is set): + // Measurement of how impactful for the prediction returned for the given row + // the value in this column was. Specifically, the feature importance + // specifies the marginal contribution that the feature made to the prediction + // score compared to the baseline score. These values are computed using the + // Sampled Shapley method. + float feature_importance = 3; +} diff --git a/google/cloud/automl_v1beta1/proto/temporal.proto b/google/cloud/automl_v1beta1/proto/temporal.proto new file mode 100644 index 00000000..76db8887 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/temporal.proto @@ -0,0 +1,37 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/protobuf/duration.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A time period inside of an example that has a time dimension (e.g. video). +message TimeSegment { + // Start of the time segment (inclusive), represented as the duration since + // the example start. + google.protobuf.Duration start_time_offset = 1; + + // End of the time segment (exclusive), represented as the duration since the + // example start. + google.protobuf.Duration end_time_offset = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/text.proto b/google/cloud/automl_v1beta1/proto/text.proto new file mode 100644 index 00000000..f6f33185 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/text.proto @@ -0,0 +1,65 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "TextProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Dataset metadata for classification. +message TextClassificationDatasetMetadata { + // Required. Type of the classification problem. + ClassificationType classification_type = 1; +} + +// Model metadata that is specific to text classification. +message TextClassificationModelMetadata { + // Output only. Classification type of the dataset used to train this model. + ClassificationType classification_type = 3; +} + +// Dataset metadata that is specific to text extraction +message TextExtractionDatasetMetadata { + +} + +// Model metadata that is specific to text extraction. +message TextExtractionModelMetadata { + +} + +// Dataset metadata for text sentiment. +message TextSentimentDatasetMetadata { + // Required. A sentiment is expressed as an integer ordinal, where higher value + // means a more positive sentiment. The range of sentiments that will be used + // is between 0 and sentiment_max (inclusive on both ends), and all the values + // in the range must be represented in the dataset before a model can be + // created. + // sentiment_max value must be between 1 and 10 (inclusive). + int32 sentiment_max = 1; +} + +// Model metadata that is specific to text sentiment. +message TextSentimentModelMetadata { + +} diff --git a/google/cloud/automl_v1beta1/proto/text_extraction.proto b/google/cloud/automl_v1beta1/proto/text_extraction.proto new file mode 100644 index 00000000..cfb0e0b3 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/text_extraction.proto @@ -0,0 +1,68 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/text_segment.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Annotation for identifying spans of text. +message TextExtractionAnnotation { + // Required. Text extraction annotations can either be a text segment or a + // text relation. + oneof annotation { + // An entity annotation will set this, which is the part of the original + // text to which the annotation pertains. + TextSegment text_segment = 3; + } + + // Output only. A confidence estimate between 0.0 and 1.0. A higher value + // means greater confidence in correctness of the annotation. + float score = 1; +} + +// Model evaluation metrics for text extraction problems. +message TextExtractionEvaluationMetrics { + // Metrics for a single confidence threshold. + message ConfidenceMetricsEntry { + // Output only. The confidence threshold value used to compute the metrics. + // Only annotations with score of at least this threshold are considered to + // be ones the model would return. + float confidence_threshold = 1; + + // Output only. Recall under the given confidence threshold. + float recall = 3; + + // Output only. Precision under the given confidence threshold. + float precision = 4; + + // Output only. The harmonic mean of recall and precision. + float f1_score = 5; + } + + // Output only. The Area under precision recall curve metric. + float au_prc = 1; + + // Output only. Metrics that have confidence thresholds. + // Precision-recall curve can be derived from it. + repeated ConfidenceMetricsEntry confidence_metrics_entries = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/text_segment.proto b/google/cloud/automl_v1beta1/proto/text_segment.proto new file mode 100644 index 00000000..94b17d93 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/text_segment.proto @@ -0,0 +1,41 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "TextSegmentProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// A contiguous part of a text (string), assuming it has an UTF-8 NFC encoding. +message TextSegment { + // Output only. The content of the TextSegment. + string content = 3; + + // Required. Zero-based character index of the first character of the text + // segment (counting characters from the beginning of the text). + int64 start_offset = 1; + + // Required. Zero-based character index of the first character past the end of + // the text segment (counting character from the beginning of the text). + // The character at the end_offset is NOT included in the text segment. + int64 end_offset = 2; +} diff --git a/google/cloud/automl_v1beta1/proto/text_sentiment.proto b/google/cloud/automl_v1beta1/proto/text_sentiment.proto new file mode 100644 index 00000000..5444c52b --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/text_sentiment.proto @@ -0,0 +1,80 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_outer_classname = "TextSentimentProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Contains annotation details specific to text sentiment. +message TextSentimentAnnotation { + // Output only. The sentiment with the semantic, as given to the + // [AutoMl.ImportData][google.cloud.automl.v1beta1.AutoMl.ImportData] when populating the dataset from which the model used + // for the prediction had been trained. + // The sentiment values are between 0 and + // Dataset.text_sentiment_dataset_metadata.sentiment_max (inclusive), + // with higher value meaning more positive sentiment. They are completely + // relative, i.e. 0 means least positive sentiment and sentiment_max means + // the most positive from the sentiments present in the train data. Therefore + // e.g. if train data had only negative sentiment, then sentiment_max, would + // be still negative (although least negative). + // The sentiment shouldn't be confused with "score" or "magnitude" + // from the previous Natural Language Sentiment Analysis API. + int32 sentiment = 1; +} + +// Model evaluation metrics for text sentiment problems. +message TextSentimentEvaluationMetrics { + // Output only. Precision. + float precision = 1; + + // Output only. Recall. + float recall = 2; + + // Output only. The harmonic mean of recall and precision. + float f1_score = 3; + + // Output only. Mean absolute error. Only set for the overall model + // evaluation, not for evaluation of a single annotation spec. + float mean_absolute_error = 4; + + // Output only. Mean squared error. Only set for the overall model + // evaluation, not for evaluation of a single annotation spec. + float mean_squared_error = 5; + + // Output only. Linear weighted kappa. Only set for the overall model + // evaluation, not for evaluation of a single annotation spec. + float linear_kappa = 6; + + // Output only. Quadratic weighted kappa. Only set for the overall model + // evaluation, not for evaluation of a single annotation spec. + float quadratic_kappa = 7; + + // Output only. Confusion matrix of the evaluation. + // Only set for the overall model evaluation, not for evaluation of a single + // annotation spec. + ClassificationEvaluationMetrics.ConfusionMatrix confusion_matrix = 8; + + // Output only. The annotation spec ids used for this evaluation. + // Deprecated . + repeated string annotation_spec_id = 9 [deprecated = true]; +} diff --git a/google/cloud/automl_v1beta1/proto/translation.proto b/google/cloud/automl_v1beta1/proto/translation.proto new file mode 100644 index 00000000..8585bd41 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/translation.proto @@ -0,0 +1,69 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/api/field_behavior.proto"; +import "google/cloud/automl/v1beta1/data_items.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "TranslationProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Dataset metadata that is specific to translation. +message TranslationDatasetMetadata { + // Required. The BCP-47 language code of the source language. + string source_language_code = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. The BCP-47 language code of the target language. + string target_language_code = 2 [(google.api.field_behavior) = REQUIRED]; +} + +// Evaluation metrics for the dataset. +message TranslationEvaluationMetrics { + // Output only. BLEU score. + double bleu_score = 1; + + // Output only. BLEU score for base model. + double base_bleu_score = 2; +} + +// Model metadata that is specific to translation. +message TranslationModelMetadata { + // The resource name of the model to use as a baseline to train the custom + // model. If unset, we use the default base model provided by Google + // Translate. Format: + // `projects/{project_id}/locations/{location_id}/models/{model_id}` + string base_model = 1; + + // Output only. Inferred from the dataset. + // The source languge (The BCP-47 language code) that is used for training. + string source_language_code = 2; + + // Output only. The target languge (The BCP-47 language code) that is used for + // training. + string target_language_code = 3; +} + +// Annotation details specific to translation. +message TranslationAnnotation { + // Output only . The translated content. + TextSnippet translated_content = 1; +} diff --git a/google/cloud/automl_v1beta1/proto/video.proto b/google/cloud/automl_v1beta1/proto/video.proto new file mode 100644 index 00000000..268ae2a8 --- /dev/null +++ b/google/cloud/automl_v1beta1/proto/video.proto @@ -0,0 +1,48 @@ +// Copyright 2020 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.automl.v1beta1; + +import "google/cloud/automl/v1beta1/classification.proto"; +import "google/api/annotations.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/automl/v1beta1;automl"; +option java_multiple_files = true; +option java_outer_classname = "VideoProto"; +option java_package = "com.google.cloud.automl.v1beta1"; +option php_namespace = "Google\\Cloud\\AutoMl\\V1beta1"; +option ruby_package = "Google::Cloud::AutoML::V1beta1"; + +// Dataset metadata specific to video classification. +// All Video Classification datasets are treated as multi label. +message VideoClassificationDatasetMetadata { + +} + +// Dataset metadata specific to video object tracking. +message VideoObjectTrackingDatasetMetadata { + +} + +// Model metadata specific to video classification. +message VideoClassificationModelMetadata { + +} + +// Model metadata specific to video object tracking. +message VideoObjectTrackingModelMetadata { + +} diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index 5c6d1f5b..b7a10974 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -28,8 +28,8 @@ from google.auth import credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1beta1.services.auto_ml import pagers from google.cloud.automl_v1beta1.types import annotation_spec from google.cloud.automl_v1beta1.types import classification @@ -87,13 +87,14 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT + column_spec_path = staticmethod(AutoMlClient.column_spec_path) + parse_column_spec_path = staticmethod(AutoMlClient.parse_column_spec_path) dataset_path = staticmethod(AutoMlClient.dataset_path) - + parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) model_path = staticmethod(AutoMlClient.model_path) - - column_spec_path = staticmethod(AutoMlClient.column_spec_path) - + parse_model_path = staticmethod(AutoMlClient.parse_model_path) table_spec_path = staticmethod(AutoMlClient.table_spec_path) + parse_table_spec_path = staticmethod(AutoMlClient.parse_table_spec_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file @@ -124,16 +125,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1beta1/services/auto_ml/client.py b/google/cloud/automl_v1beta1/services/auto_ml/client.py index 9416b524..6ae4f4c2 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/client.py @@ -16,22 +16,24 @@ # from collections import OrderedDict +from distutils import util import os import re -from typing import Callable, Dict, Sequence, Tuple, Type, Union +from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore +from google.api_core import client_options as client_options_lib # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1beta1.services.auto_ml import pagers from google.cloud.automl_v1beta1.types import annotation_spec from google.cloud.automl_v1beta1.types import classification @@ -244,9 +246,9 @@ def parse_table_spec_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: credentials.Credentials = None, - transport: Union[str, AutoMlTransport] = None, - client_options: ClientOptions = None, + credentials: Optional[credentials.Credentials] = None, + transport: Union[str, AutoMlTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the auto ml client. @@ -260,19 +262,22 @@ def __init__( transport (Union[str, ~.AutoMlTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. + client_options (client_options_lib.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -284,29 +289,47 @@ def __init__( creation failed for any reason. """ if isinstance(client_options, dict): - client_options = ClientOptions.from_dict(client_options) + client_options = client_options_lib.from_dict(client_options) if client_options is None: - client_options = ClientOptions.ClientOptions() + client_options = client_options_lib.ClientOptions() - if client_options.api_endpoint is None: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + ssl_credentials = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + import grpc # type: ignore + + cert, key = client_options.client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + is_mtls = True + else: + creds = SslCredentials() + is_mtls = creds.is_mtls + ssl_credentials = creds.ssl_credentials if is_mtls else None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") if use_mtls_env == "never": - client_options.api_endpoint = self.DEFAULT_ENDPOINT + api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - has_client_cert_source = ( - client_options.client_cert_source is not None - or mtls.has_default_client_cert_source() - ) - client_options.api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT - if has_client_cert_source - else self.DEFAULT_ENDPOINT + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -330,10 +353,9 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=client_options.api_endpoint, + host=api_endpoint, scopes=client_options.scopes, - api_mtls_endpoint=client_options.api_endpoint, - client_cert_source=client_options.client_cert_source, + ssl_channel_credentials=ssl_credentials, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py index d50f2201..642c9f7b 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth +from google import auth # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py index a3c183e4..a8cb2fd7 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py @@ -15,6 +15,7 @@ # limitations under the License. # +import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -24,7 +25,6 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore - import grpc # type: ignore from google.cloud.automl_v1beta1.types import annotation_spec @@ -81,6 +81,7 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -101,14 +102,16 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -131,6 +134,11 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -161,6 +169,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) self._stubs = {} # type: Dict[str, Callable] @@ -226,13 +251,6 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py index c8d24dad..a977ad45 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py @@ -15,11 +15,13 @@ # limitations under the License. # +import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore +from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -123,6 +125,7 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -144,14 +147,16 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -174,12 +179,22 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -199,6 +214,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) # Run the base constructor. super().__init__( @@ -219,13 +251,6 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py index cd313402..c204325b 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py @@ -28,8 +28,8 @@ from google.auth import credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1beta1.types import annotation_payload from google.cloud.automl_v1beta1.types import data_items from google.cloud.automl_v1beta1.types import io @@ -82,16 +82,19 @@ def __init__( client_options (ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport diff --git a/google/cloud/automl_v1beta1/services/prediction_service/client.py b/google/cloud/automl_v1beta1/services/prediction_service/client.py index 81cb0649..78ec510c 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/client.py @@ -16,22 +16,24 @@ # from collections import OrderedDict +from distutils import util import os import re -from typing import Callable, Dict, Sequence, Tuple, Type, Union +from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore +from google.api_core import client_options as client_options_lib # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -from google.api_core import operation -from google.api_core import operation_async +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.automl_v1beta1.types import annotation_payload from google.cloud.automl_v1beta1.types import data_items from google.cloud.automl_v1beta1.types import io @@ -142,9 +144,9 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): def __init__( self, *, - credentials: credentials.Credentials = None, - transport: Union[str, PredictionServiceTransport] = None, - client_options: ClientOptions = None, + credentials: Optional[credentials.Credentials] = None, + transport: Union[str, PredictionServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the prediction service client. @@ -158,19 +160,22 @@ def __init__( transport (Union[str, ~.PredictionServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (ClientOptions): Custom options for the client. It - won't take effect if a ``transport`` instance is provided. + client_options (client_options_lib.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. GOOGLE_API_USE_MTLS + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT environment variable can also be used to override the endpoint: "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint, this is the default value for - the environment variable) and "auto" (auto switch to the default - mTLS endpoint if client SSL credentials is present). However, - the ``api_endpoint`` property takes precedence if provided. - (2) The ``client_cert_source`` property is used to provide client - SSL credentials for mutual TLS transport. If not provided, the - default SSL credentials will be used if present. + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. client_info (google.api_core.gapic_v1.client_info.ClientInfo): The client info used to send a user-agent string along with API requests. If ``None``, then default info will be used. @@ -182,29 +187,47 @@ def __init__( creation failed for any reason. """ if isinstance(client_options, dict): - client_options = ClientOptions.from_dict(client_options) + client_options = client_options_lib.from_dict(client_options) if client_options is None: - client_options = ClientOptions.ClientOptions() + client_options = client_options_lib.ClientOptions() - if client_options.api_endpoint is None: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + ssl_credentials = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + import grpc # type: ignore + + cert, key = client_options.client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + is_mtls = True + else: + creds = SslCredentials() + is_mtls = creds.is_mtls + ssl_credentials = creds.ssl_credentials if is_mtls else None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") if use_mtls_env == "never": - client_options.api_endpoint = self.DEFAULT_ENDPOINT + api_endpoint = self.DEFAULT_ENDPOINT elif use_mtls_env == "always": - client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - has_client_cert_source = ( - client_options.client_cert_source is not None - or mtls.has_default_client_cert_source() - ) - client_options.api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT - if has_client_cert_source - else self.DEFAULT_ENDPOINT + api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT ) else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" ) # Save or instantiate the transport. @@ -228,10 +251,9 @@ def __init__( self._transport = Transport( credentials=credentials, credentials_file=client_options.credentials_file, - host=client_options.api_endpoint, + host=api_endpoint, scopes=client_options.scopes, - api_mtls_endpoint=client_options.api_endpoint, - client_cert_source=client_options.client_cert_source, + ssl_channel_credentials=ssl_credentials, quota_project_id=client_options.quota_project_id, client_info=client_info, ) diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py index bb674eca..04857f4c 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/base.py @@ -19,7 +19,7 @@ import typing import pkg_resources -from google import auth +from google import auth # type: ignore from google.api_core import exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py index 9bc30cdd..3c484247 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py @@ -15,6 +15,7 @@ # limitations under the License. # +import warnings from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore @@ -24,7 +25,6 @@ from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore - import grpc # type: ignore from google.cloud.automl_v1beta1.types import prediction_service @@ -61,6 +61,7 @@ def __init__( channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -81,14 +82,16 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -111,6 +114,11 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint @@ -141,6 +149,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) self._stubs = {} # type: Dict[str, Callable] @@ -206,13 +231,6 @@ def grpc_channel(self) -> grpc.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py index 2c7d9712..0b1bb638 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py @@ -15,11 +15,13 @@ # limitations under the License. # +import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore +from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -103,6 +105,7 @@ def __init__( channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -124,14 +127,16 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from ``client_cert_source`` or applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A - callback to provide client SSL certificate bytes and private key - bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` - is None. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -154,12 +159,22 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel elif api_mtls_endpoint: + warnings.warn( + "api_mtls_endpoint and client_cert_source are deprecated", + DeprecationWarning, + ) + host = ( api_mtls_endpoint if ":" in api_mtls_endpoint else api_mtls_endpoint + ":443" ) + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -179,6 +194,23 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + else: + host = host if ":" in host else host + ":443" + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_channel_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) # Run the base constructor. super().__init__( @@ -199,13 +231,6 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel diff --git a/google/cloud/automl_v1beta1/types/classification.py b/google/cloud/automl_v1beta1/types/classification.py index 8c879bf2..4b5e5a2a 100644 --- a/google/cloud/automl_v1beta1/types/classification.py +++ b/google/cloud/automl_v1beta1/types/classification.py @@ -60,7 +60,7 @@ class VideoClassificationAnnotation(proto.Message): r"""Contains annotation details specific to video classification. Attributes: - type (str): + type_ (str): Output only. Expresses the type of video classification. Possible values: @@ -96,7 +96,7 @@ class VideoClassificationAnnotation(proto.Message): to which the annotation applies. """ - type = proto.Field(proto.STRING, number=1) + type_ = proto.Field(proto.STRING, number=1) classification_annotation = proto.Field( proto.MESSAGE, number=2, message=ClassificationAnnotation, diff --git a/google/cloud/automl_v1beta1/types/data_stats.py b/google/cloud/automl_v1beta1/types/data_stats.py index 4ae40fc8..4405185f 100644 --- a/google/cloud/automl_v1beta1/types/data_stats.py +++ b/google/cloud/automl_v1beta1/types/data_stats.py @@ -115,9 +115,9 @@ class HistogramBucket(proto.Message): r"""A bucket of a histogram. Attributes: - min (float): + min_ (float): The minimum value of the bucket, inclusive. - max (float): + max_ (float): The maximum value of the bucket, exclusive unless max = ``"Infinity"``, in which case it's inclusive. count (int): @@ -125,9 +125,9 @@ class HistogramBucket(proto.Message): bucket, i.e. are between min and max values. """ - min = proto.Field(proto.DOUBLE, number=1) + min_ = proto.Field(proto.DOUBLE, number=1) - max = proto.Field(proto.DOUBLE, number=2) + max_ = proto.Field(proto.DOUBLE, number=2) count = proto.Field(proto.INT64, number=3) diff --git a/noxfile.py b/noxfile.py index 9c69b3b7..709afdde 100644 --- a/noxfile.py +++ b/noxfile.py @@ -74,7 +74,6 @@ def default(session): session.install("mock", "pytest", "pytest-cov") session.install("-e", ".[pandas,storage]") - session.install("proto-plus==1.8.1") # Run py.test against the unit tests. session.run( @@ -199,36 +198,3 @@ def docfx(session): os.path.join("docs", ""), os.path.join("docs", "_build", "html", ""), ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def docfx(session): - """Build the docfx yaml files for this library.""" - - session.install("-e", ".[pandas,storage]") - session.install("sphinx<3.0.0", "alabaster", "recommonmark", "sphinx-docfx-yaml") - - shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) - session.run( - "sphinx-build", - "-T", # show full traceback on exception - "-N", # no colors - "-D", - ( - "extensions=sphinx.ext.autodoc," - "sphinx.ext.autosummary," - "docfx_yaml.extension," - "sphinx.ext.intersphinx," - "sphinx.ext.coverage," - "sphinx.ext.napoleon," - "sphinx.ext.todo," - "sphinx.ext.viewcode," - "recommonmark" - ), - "-b", - "html", - "-d", - os.path.join("docs", "_build", "doctrees", ""), - os.path.join("docs", ""), - os.path.join("docs", "_build", "html", ""), - ) diff --git a/synth.metadata b/synth.metadata index 6c3bc216..690d358b 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,16 +3,16 @@ { "git": { "name": ".", - "remote": "git@github.com:googleapis/python-automl", - "sha": "9b218b1f1cd0caef664e51064baf5f4af07a97c1" + "remote": "https://github.com/googleapis/python-automl.git", + "sha": "8c7d54872a6e5628171f160e1a39a067d5f46563" } }, { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "17de2b31f9450385e739bedeeaac6e1ec4f239a8", - "internalRef": "327504150" + "sha": "d3697d47929f34c43bcc4de16c7c761a80e97cf1", + "internalRef": "333502684" } }, { @@ -49,5 +49,221 @@ "generator": "bazel" } } + ], + "generatedFiles": [ + ".coveragerc", + ".flake8", + ".github/CONTRIBUTING.md", + ".github/ISSUE_TEMPLATE/bug_report.md", + ".github/ISSUE_TEMPLATE/feature_request.md", + ".github/ISSUE_TEMPLATE/support_request.md", + ".github/PULL_REQUEST_TEMPLATE.md", + ".github/release-please.yml", + ".gitignore", + ".kokoro/build.sh", + ".kokoro/continuous/common.cfg", + ".kokoro/continuous/continuous.cfg", + ".kokoro/docker/docs/Dockerfile", + ".kokoro/docker/docs/fetch_gpg_keys.sh", + ".kokoro/docs/common.cfg", + ".kokoro/docs/docs-presubmit.cfg", + ".kokoro/docs/docs.cfg", + ".kokoro/presubmit/common.cfg", + ".kokoro/presubmit/presubmit.cfg", + ".kokoro/publish-docs.sh", + ".kokoro/release.sh", + ".kokoro/release/common.cfg", + ".kokoro/release/release.cfg", + ".kokoro/samples/lint/common.cfg", + ".kokoro/samples/lint/continuous.cfg", + ".kokoro/samples/lint/periodic.cfg", + ".kokoro/samples/lint/presubmit.cfg", + ".kokoro/samples/python3.6/common.cfg", + ".kokoro/samples/python3.6/continuous.cfg", + ".kokoro/samples/python3.6/periodic.cfg", + ".kokoro/samples/python3.6/presubmit.cfg", + ".kokoro/samples/python3.7/common.cfg", + ".kokoro/samples/python3.7/continuous.cfg", + ".kokoro/samples/python3.7/periodic.cfg", + ".kokoro/samples/python3.7/presubmit.cfg", + ".kokoro/samples/python3.8/common.cfg", + ".kokoro/samples/python3.8/continuous.cfg", + ".kokoro/samples/python3.8/periodic.cfg", + ".kokoro/samples/python3.8/presubmit.cfg", + ".kokoro/test-samples.sh", + ".kokoro/trampoline.sh", + ".kokoro/trampoline_v2.sh", + ".trampolinerc", + "CODE_OF_CONDUCT.md", + "CONTRIBUTING.rst", + "LICENSE", + "MANIFEST.in", + "docs/_static/custom.css", + "docs/_templates/layout.html", + "docs/automl_v1/services.rst", + "docs/automl_v1/types.rst", + "docs/automl_v1beta1/services.rst", + "docs/automl_v1beta1/types.rst", + "docs/conf.py", + "docs/multiprocessing.rst", + "google/cloud/automl/__init__.py", + "google/cloud/automl/py.typed", + "google/cloud/automl_v1/__init__.py", + "google/cloud/automl_v1/proto/annotation_payload.proto", + "google/cloud/automl_v1/proto/annotation_spec.proto", + "google/cloud/automl_v1/proto/classification.proto", + "google/cloud/automl_v1/proto/data_items.proto", + "google/cloud/automl_v1/proto/dataset.proto", + "google/cloud/automl_v1/proto/detection.proto", + "google/cloud/automl_v1/proto/geometry.proto", + "google/cloud/automl_v1/proto/image.proto", + "google/cloud/automl_v1/proto/io.proto", + "google/cloud/automl_v1/proto/model.proto", + "google/cloud/automl_v1/proto/model_evaluation.proto", + "google/cloud/automl_v1/proto/operations.proto", + "google/cloud/automl_v1/proto/prediction_service.proto", + "google/cloud/automl_v1/proto/service.proto", + "google/cloud/automl_v1/proto/text.proto", + "google/cloud/automl_v1/proto/text_extraction.proto", + "google/cloud/automl_v1/proto/text_segment.proto", + "google/cloud/automl_v1/proto/text_sentiment.proto", + "google/cloud/automl_v1/proto/translation.proto", + "google/cloud/automl_v1/py.typed", + "google/cloud/automl_v1/services/__init__.py", + "google/cloud/automl_v1/services/auto_ml/__init__.py", + "google/cloud/automl_v1/services/auto_ml/async_client.py", + "google/cloud/automl_v1/services/auto_ml/client.py", + "google/cloud/automl_v1/services/auto_ml/pagers.py", + "google/cloud/automl_v1/services/auto_ml/transports/__init__.py", + "google/cloud/automl_v1/services/auto_ml/transports/base.py", + "google/cloud/automl_v1/services/auto_ml/transports/grpc.py", + "google/cloud/automl_v1/services/auto_ml/transports/grpc_asyncio.py", + "google/cloud/automl_v1/services/prediction_service/__init__.py", + "google/cloud/automl_v1/services/prediction_service/async_client.py", + "google/cloud/automl_v1/services/prediction_service/client.py", + "google/cloud/automl_v1/services/prediction_service/transports/__init__.py", + "google/cloud/automl_v1/services/prediction_service/transports/base.py", + "google/cloud/automl_v1/services/prediction_service/transports/grpc.py", + "google/cloud/automl_v1/services/prediction_service/transports/grpc_asyncio.py", + "google/cloud/automl_v1/types/__init__.py", + "google/cloud/automl_v1/types/annotation_payload.py", + "google/cloud/automl_v1/types/annotation_spec.py", + "google/cloud/automl_v1/types/classification.py", + "google/cloud/automl_v1/types/data_items.py", + "google/cloud/automl_v1/types/dataset.py", + "google/cloud/automl_v1/types/detection.py", + "google/cloud/automl_v1/types/geometry.py", + "google/cloud/automl_v1/types/image.py", + "google/cloud/automl_v1/types/io.py", + "google/cloud/automl_v1/types/model.py", + "google/cloud/automl_v1/types/model_evaluation.py", + "google/cloud/automl_v1/types/operations.py", + "google/cloud/automl_v1/types/prediction_service.py", + "google/cloud/automl_v1/types/service.py", + "google/cloud/automl_v1/types/text.py", + "google/cloud/automl_v1/types/text_extraction.py", + "google/cloud/automl_v1/types/text_segment.py", + "google/cloud/automl_v1/types/text_sentiment.py", + "google/cloud/automl_v1/types/translation.py", + "google/cloud/automl_v1beta1/__init__.py", + "google/cloud/automl_v1beta1/proto/annotation_payload.proto", + "google/cloud/automl_v1beta1/proto/annotation_spec.proto", + "google/cloud/automl_v1beta1/proto/classification.proto", + "google/cloud/automl_v1beta1/proto/column_spec.proto", + "google/cloud/automl_v1beta1/proto/data_items.proto", + "google/cloud/automl_v1beta1/proto/data_stats.proto", + "google/cloud/automl_v1beta1/proto/data_types.proto", + "google/cloud/automl_v1beta1/proto/dataset.proto", + "google/cloud/automl_v1beta1/proto/detection.proto", + "google/cloud/automl_v1beta1/proto/geometry.proto", + "google/cloud/automl_v1beta1/proto/image.proto", + "google/cloud/automl_v1beta1/proto/io.proto", + "google/cloud/automl_v1beta1/proto/model.proto", + "google/cloud/automl_v1beta1/proto/model_evaluation.proto", + "google/cloud/automl_v1beta1/proto/operations.proto", + "google/cloud/automl_v1beta1/proto/prediction_service.proto", + "google/cloud/automl_v1beta1/proto/ranges.proto", + "google/cloud/automl_v1beta1/proto/regression.proto", + "google/cloud/automl_v1beta1/proto/service.proto", + "google/cloud/automl_v1beta1/proto/table_spec.proto", + "google/cloud/automl_v1beta1/proto/tables.proto", + "google/cloud/automl_v1beta1/proto/temporal.proto", + "google/cloud/automl_v1beta1/proto/text.proto", + "google/cloud/automl_v1beta1/proto/text_extraction.proto", + "google/cloud/automl_v1beta1/proto/text_segment.proto", + "google/cloud/automl_v1beta1/proto/text_sentiment.proto", + "google/cloud/automl_v1beta1/proto/translation.proto", + "google/cloud/automl_v1beta1/proto/video.proto", + "google/cloud/automl_v1beta1/py.typed", + "google/cloud/automl_v1beta1/services/__init__.py", + "google/cloud/automl_v1beta1/services/auto_ml/__init__.py", + "google/cloud/automl_v1beta1/services/auto_ml/async_client.py", + "google/cloud/automl_v1beta1/services/auto_ml/client.py", + "google/cloud/automl_v1beta1/services/auto_ml/pagers.py", + "google/cloud/automl_v1beta1/services/auto_ml/transports/__init__.py", + "google/cloud/automl_v1beta1/services/auto_ml/transports/base.py", + "google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py", + "google/cloud/automl_v1beta1/services/auto_ml/transports/grpc_asyncio.py", + "google/cloud/automl_v1beta1/services/prediction_service/__init__.py", + "google/cloud/automl_v1beta1/services/prediction_service/async_client.py", + "google/cloud/automl_v1beta1/services/prediction_service/client.py", + "google/cloud/automl_v1beta1/services/prediction_service/transports/__init__.py", + "google/cloud/automl_v1beta1/services/prediction_service/transports/base.py", + "google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py", + "google/cloud/automl_v1beta1/services/prediction_service/transports/grpc_asyncio.py", + "google/cloud/automl_v1beta1/types/__init__.py", + "google/cloud/automl_v1beta1/types/annotation_payload.py", + "google/cloud/automl_v1beta1/types/annotation_spec.py", + "google/cloud/automl_v1beta1/types/classification.py", + "google/cloud/automl_v1beta1/types/column_spec.py", + "google/cloud/automl_v1beta1/types/data_items.py", + "google/cloud/automl_v1beta1/types/data_stats.py", + "google/cloud/automl_v1beta1/types/data_types.py", + "google/cloud/automl_v1beta1/types/dataset.py", + "google/cloud/automl_v1beta1/types/detection.py", + "google/cloud/automl_v1beta1/types/geometry.py", + "google/cloud/automl_v1beta1/types/image.py", + "google/cloud/automl_v1beta1/types/io.py", + "google/cloud/automl_v1beta1/types/model.py", + "google/cloud/automl_v1beta1/types/model_evaluation.py", + "google/cloud/automl_v1beta1/types/operations.py", + "google/cloud/automl_v1beta1/types/prediction_service.py", + "google/cloud/automl_v1beta1/types/ranges.py", + "google/cloud/automl_v1beta1/types/regression.py", + "google/cloud/automl_v1beta1/types/service.py", + "google/cloud/automl_v1beta1/types/table_spec.py", + "google/cloud/automl_v1beta1/types/tables.py", + "google/cloud/automl_v1beta1/types/temporal.py", + "google/cloud/automl_v1beta1/types/text.py", + "google/cloud/automl_v1beta1/types/text_extraction.py", + "google/cloud/automl_v1beta1/types/text_segment.py", + "google/cloud/automl_v1beta1/types/text_sentiment.py", + "google/cloud/automl_v1beta1/types/translation.py", + "google/cloud/automl_v1beta1/types/video.py", + "mypy.ini", + "noxfile.py", + "renovate.json", + "samples/AUTHORING_GUIDE.md", + "samples/CONTRIBUTING.md", + "samples/beta/noxfile.py", + "samples/snippets/noxfile.py", + "samples/tables/noxfile.py", + "scripts/decrypt-secrets.sh", + "scripts/fixup_automl_v1_keywords.py", + "scripts/fixup_automl_v1beta1_keywords.py", + "scripts/readme-gen/readme_gen.py", + "scripts/readme-gen/templates/README.tmpl.rst", + "scripts/readme-gen/templates/auth.tmpl.rst", + "scripts/readme-gen/templates/auth_api_key.tmpl.rst", + "scripts/readme-gen/templates/install_deps.tmpl.rst", + "scripts/readme-gen/templates/install_portaudio.tmpl.rst", + "setup.cfg", + "testing/.gitignore", + "tests/unit/gapic/automl_v1/__init__.py", + "tests/unit/gapic/automl_v1/test_auto_ml.py", + "tests/unit/gapic/automl_v1/test_prediction_service.py", + "tests/unit/gapic/automl_v1beta1/__init__.py", + "tests/unit/gapic/automl_v1beta1/test_auto_ml.py", + "tests/unit/gapic/automl_v1beta1/test_prediction_service.py" ] } \ No newline at end of file diff --git a/tests/unit/gapic/automl_v1/test_auto_ml.py b/tests/unit/gapic/automl_v1/test_auto_ml.py index 42ad394e..a11480cd 100644 --- a/tests/unit/gapic/automl_v1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1/test_auto_ml.py @@ -31,7 +31,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.api_core import operation_async +from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 from google.auth import credentials from google.auth.exceptions import MutualTLSChannelError @@ -158,15 +158,14 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -175,15 +174,14 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -192,95 +190,171 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "true"), + ( + AutoMlAsyncClient, + transports.AutoMlGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "false"), + ( + AutoMlAsyncClient, + transports.AutoMlGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + AutoMlClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlClient) +) +@mock.patch.object( + AutoMlAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlAsyncClient) +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_auto_ml_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=client_cert_source_callback, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and default_client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): - with mock.patch.object(transport_class, "__init__") as patched: + ssl_channel_creds = mock.Mock() with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, + "grpc.ssl_channel_credentials", return_value=ssl_channel_creds ): patched.return_value = None - client = client_class() + client = client_class(client_options=options) + + if use_client_cert_env == "false": + expected_ssl_channel_creds = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_ssl_channel_creds = ssl_channel_creds + expected_host = client.DEFAULT_MTLS_ENDPOINT + patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, + host=expected_host, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=expected_ssl_channel_creds, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", but client_cert_source and default_client_cert_source are None. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None ): - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.ssl_credentials", + new_callable=mock.PropertyMock, + ) as ssl_credentials_mock: + if use_client_cert_env == "false": + is_mtls_mock.return_value = False + ssl_credentials_mock.return_value = None + expected_host = client.DEFAULT_ENDPOINT + expected_ssl_channel_creds = None + else: + is_mtls_mock.return_value = True + ssl_credentials_mock.return_value = mock.Mock() + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_ssl_channel_creds = ( + ssl_credentials_mock.return_value + ) + + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + ssl_channel_credentials=expected_ssl_channel_creds, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + ): + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + is_mtls_mock.return_value = False + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -303,8 +377,7 @@ def test_auto_ml_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -330,8 +403,7 @@ def test_auto_ml_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -348,8 +420,7 @@ def test_auto_ml_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -1038,8 +1109,8 @@ def test_list_datasets_pages(): RuntimeError, ) pages = list(client.list_datasets(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -1103,10 +1174,10 @@ async def test_list_datasets_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_datasets(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_datasets(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_update_dataset( @@ -2862,8 +2933,8 @@ def test_list_models_pages(): RuntimeError, ) pages = list(client.list_models(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -2919,10 +2990,10 @@ async def test_list_models_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_models(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_models(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelRequest): @@ -4459,8 +4530,8 @@ def test_list_model_evaluations_pages(): RuntimeError, ) pages = list(client.list_model_evaluations(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -4544,10 +4615,10 @@ async def test_list_model_evaluations_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_model_evaluations(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_model_evaluations(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_credentials_transport_error(): @@ -4604,6 +4675,18 @@ def test_transport_get_channel(): assert channel +@pytest.mark.parametrize( + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4680,6 +4763,17 @@ def test_auto_ml_base_transport_with_credentials_file(): ) +def test_auto_ml_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(auth, "default") as adc, mock.patch( + "google.cloud.automl_v1.services.auto_ml.transports.AutoMlTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.AutoMlTransport() + adc.assert_called_once() + + def test_auto_ml_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -4728,179 +4822,102 @@ def test_auto_ml_host_with_port(): def test_auto_ml_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called def test_auto_ml_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_auto_ml_grpc_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], ) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_auto_ml_grpc_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - mock_cred = mock.Mock() - transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel +def test_auto_ml_transport_channel_mtls_with_client_cert_source(transport_class): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], ) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. +def test_auto_ml_transport_channel_mtls_with_adc(transport_class): mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - mock_cred = mock.Mock() - transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_auto_ml_grpc_lro_client(): @@ -4929,53 +4946,53 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_model_path(): +def test_dataset_path(): project = "squid" location = "clam" - model = "whelk" + dataset = "whelk" - expected = "projects/{project}/locations/{location}/models/{model}".format( - project=project, location=location, model=model, + expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( + project=project, location=location, dataset=dataset, ) - actual = AutoMlClient.model_path(project, location, model) + actual = AutoMlClient.dataset_path(project, location, dataset) assert expected == actual -def test_parse_model_path(): +def test_parse_dataset_path(): expected = { "project": "octopus", "location": "oyster", - "model": "nudibranch", + "dataset": "nudibranch", } - path = AutoMlClient.model_path(**expected) + path = AutoMlClient.dataset_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_model_path(path) + actual = AutoMlClient.parse_dataset_path(path) assert expected == actual -def test_dataset_path(): +def test_model_path(): project = "squid" location = "clam" - dataset = "whelk" + model = "whelk" - expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( - project=project, location=location, dataset=dataset, + expected = "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, ) - actual = AutoMlClient.dataset_path(project, location, dataset) + actual = AutoMlClient.model_path(project, location, model) assert expected == actual -def test_parse_dataset_path(): +def test_parse_model_path(): expected = { "project": "octopus", "location": "oyster", - "dataset": "nudibranch", + "model": "nudibranch", } - path = AutoMlClient.dataset_path(**expected) + path = AutoMlClient.model_path(**expected) # Check that the path construction is reversible. - actual = AutoMlClient.parse_dataset_path(path) + actual = AutoMlClient.parse_model_path(path) assert expected == actual diff --git a/tests/unit/gapic/automl_v1/test_prediction_service.py b/tests/unit/gapic/automl_v1/test_prediction_service.py index a0087eae..fd886203 100644 --- a/tests/unit/gapic/automl_v1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1/test_prediction_service.py @@ -31,7 +31,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.api_core import operation_async +from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 from google.auth import credentials from google.auth.exceptions import MutualTLSChannelError @@ -167,15 +167,14 @@ def test_prediction_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -184,15 +183,14 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -201,95 +199,185 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + PredictionServiceClient, + transports.PredictionServiceGrpcTransport, + "grpc", + "true", + ), + ( + PredictionServiceAsyncClient, + transports.PredictionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + PredictionServiceClient, + transports.PredictionServiceGrpcTransport, + "grpc", + "false", + ), + ( + PredictionServiceAsyncClient, + transports.PredictionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + PredictionServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceClient), +) +@mock.patch.object( + PredictionServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_prediction_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=client_cert_source_callback, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and default_client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): - with mock.patch.object(transport_class, "__init__") as patched: + ssl_channel_creds = mock.Mock() with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, + "grpc.ssl_channel_credentials", return_value=ssl_channel_creds ): patched.return_value = None - client = client_class() + client = client_class(client_options=options) + + if use_client_cert_env == "false": + expected_ssl_channel_creds = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_ssl_channel_creds = ssl_channel_creds + expected_host = client.DEFAULT_MTLS_ENDPOINT + patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, + host=expected_host, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=expected_ssl_channel_creds, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", but client_cert_source and default_client_cert_source are None. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None ): - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.ssl_credentials", + new_callable=mock.PropertyMock, + ) as ssl_credentials_mock: + if use_client_cert_env == "false": + is_mtls_mock.return_value = False + ssl_credentials_mock.return_value = None + expected_host = client.DEFAULT_ENDPOINT + expected_ssl_channel_creds = None + else: + is_mtls_mock.return_value = True + ssl_credentials_mock.return_value = mock.Mock() + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_ssl_channel_creds = ( + ssl_credentials_mock.return_value + ) + + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + ssl_channel_credentials=expected_ssl_channel_creds, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + ): + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + is_mtls_mock.return_value = False + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -316,8 +404,7 @@ def test_prediction_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -347,8 +434,7 @@ def test_prediction_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -367,8 +453,7 @@ def test_prediction_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -904,6 +989,21 @@ def test_transport_get_channel(): assert channel +@pytest.mark.parametrize( + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -964,6 +1064,17 @@ def test_prediction_service_base_transport_with_credentials_file(): ) +def test_prediction_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(auth, "default") as adc, mock.patch( + "google.cloud.automl_v1.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport() + adc.assert_called_once() + + def test_prediction_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -1012,179 +1123,110 @@ def test_prediction_service_host_with_port(): def test_prediction_service_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called def test_prediction_service_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_prediction_service_grpc_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], ) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_prediction_service_grpc_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint +def test_prediction_service_transport_channel_mtls_with_client_cert_source( + transport_class, ): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - mock_cred = mock.Mock() - transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], ) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. +def test_prediction_service_transport_channel_mtls_with_adc(transport_class): mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - mock_cred = mock.Mock() - transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_prediction_service_grpc_lro_client(): diff --git a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py index 2464c824..09cb0749 100644 --- a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py @@ -31,7 +31,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.api_core import operation_async +from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 from google.auth import credentials from google.auth.exceptions import MutualTLSChannelError @@ -168,15 +168,14 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -185,15 +184,14 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -202,95 +200,171 @@ def test_auto_ml_client_client_options(client_class, transport_class, transport_ credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "true"), + ( + AutoMlAsyncClient, + transports.AutoMlGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + (AutoMlClient, transports.AutoMlGrpcTransport, "grpc", "false"), + ( + AutoMlAsyncClient, + transports.AutoMlGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + AutoMlClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlClient) +) +@mock.patch.object( + AutoMlAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AutoMlAsyncClient) +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_auto_ml_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=client_cert_source_callback, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and default_client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): - with mock.patch.object(transport_class, "__init__") as patched: + ssl_channel_creds = mock.Mock() with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, + "grpc.ssl_channel_credentials", return_value=ssl_channel_creds ): patched.return_value = None - client = client_class() + client = client_class(client_options=options) + + if use_client_cert_env == "false": + expected_ssl_channel_creds = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_ssl_channel_creds = ssl_channel_creds + expected_host = client.DEFAULT_MTLS_ENDPOINT + patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, + host=expected_host, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=expected_ssl_channel_creds, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", but client_cert_source and default_client_cert_source are None. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None ): - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.ssl_credentials", + new_callable=mock.PropertyMock, + ) as ssl_credentials_mock: + if use_client_cert_env == "false": + is_mtls_mock.return_value = False + ssl_credentials_mock.return_value = None + expected_host = client.DEFAULT_ENDPOINT + expected_ssl_channel_creds = None + else: + is_mtls_mock.return_value = True + ssl_credentials_mock.return_value = mock.Mock() + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_ssl_channel_creds = ( + ssl_credentials_mock.return_value + ) + + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + ssl_channel_credentials=expected_ssl_channel_creds, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + ): + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + is_mtls_mock.return_value = False + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -313,8 +387,7 @@ def test_auto_ml_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -340,8 +413,7 @@ def test_auto_ml_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -358,8 +430,7 @@ def test_auto_ml_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -1079,8 +1150,8 @@ def test_list_datasets_pages(): RuntimeError, ) pages = list(client.list_datasets(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -1144,10 +1215,10 @@ async def test_list_datasets_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_datasets(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_datasets(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_update_dataset( @@ -2711,8 +2782,8 @@ def test_list_table_specs_pages(): RuntimeError, ) pages = list(client.list_table_specs(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -2784,10 +2855,10 @@ async def test_list_table_specs_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_table_specs(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_table_specs(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_update_table_spec( @@ -3494,8 +3565,8 @@ def test_list_column_specs_pages(): RuntimeError, ) pages = list(client.list_column_specs(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -3567,10 +3638,10 @@ async def test_list_column_specs_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_column_specs(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_column_specs(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_update_column_spec( @@ -4455,8 +4526,8 @@ def test_list_models_pages(): RuntimeError, ) pages = list(client.list_models(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -4512,10 +4583,10 @@ async def test_list_models_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_models(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_models(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelRequest): @@ -6013,8 +6084,8 @@ def test_list_model_evaluations_pages(): RuntimeError, ) pages = list(client.list_model_evaluations(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -6098,10 +6169,10 @@ async def test_list_model_evaluations_async_pages(): RuntimeError, ) pages = [] - async for page in (await client.list_model_evaluations(request={})).pages: - pages.append(page) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token + async for page_ in (await client.list_model_evaluations(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token def test_credentials_transport_error(): @@ -6158,6 +6229,18 @@ def test_transport_get_channel(): assert channel +@pytest.mark.parametrize( + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -6240,6 +6323,17 @@ def test_auto_ml_base_transport_with_credentials_file(): ) +def test_auto_ml_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(auth, "default") as adc, mock.patch( + "google.cloud.automl_v1beta1.services.auto_ml.transports.AutoMlTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.AutoMlTransport() + adc.assert_called_once() + + def test_auto_ml_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -6288,179 +6382,102 @@ def test_auto_ml_host_with_port(): def test_auto_ml_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called def test_auto_ml_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_auto_ml_grpc_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], ) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_auto_ml_grpc_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - mock_cred = mock.Mock() - transport = transports.AutoMlGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel +def test_auto_ml_transport_channel_mtls_with_client_cert_source(transport_class): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [transports.AutoMlGrpcTransport, transports.AutoMlGrpcAsyncIOTransport], ) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_auto_ml_grpc_asyncio_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. +def test_auto_ml_transport_channel_mtls_with_adc(transport_class): mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - mock_cred = mock.Mock() - transport = transports.AutoMlGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_auto_ml_grpc_lro_client(): @@ -6489,6 +6506,41 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client +def test_column_spec_path(): + project = "squid" + location = "clam" + dataset = "whelk" + table_spec = "octopus" + column_spec = "oyster" + + expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}".format( + project=project, + location=location, + dataset=dataset, + table_spec=table_spec, + column_spec=column_spec, + ) + actual = AutoMlClient.column_spec_path( + project, location, dataset, table_spec, column_spec + ) + assert expected == actual + + +def test_parse_column_spec_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "dataset": "mussel", + "table_spec": "winkle", + "column_spec": "nautilus", + } + path = AutoMlClient.column_spec_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_column_spec_path(path) + assert expected == actual + + def test_dataset_path(): project = "squid" location = "clam" @@ -6539,41 +6591,6 @@ def test_parse_model_path(): assert expected == actual -def test_column_spec_path(): - project = "squid" - location = "clam" - dataset = "whelk" - table_spec = "octopus" - column_spec = "oyster" - - expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}".format( - project=project, - location=location, - dataset=dataset, - table_spec=table_spec, - column_spec=column_spec, - ) - actual = AutoMlClient.column_spec_path( - project, location, dataset, table_spec, column_spec - ) - assert expected == actual - - -def test_parse_column_spec_path(): - expected = { - "project": "nudibranch", - "location": "cuttlefish", - "dataset": "mussel", - "table_spec": "winkle", - "column_spec": "nautilus", - } - path = AutoMlClient.column_spec_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_column_spec_path(path) - assert expected == actual - - def test_table_spec_path(): project = "squid" location = "clam" diff --git a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py index c21f17b9..44c966c5 100644 --- a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py @@ -31,7 +31,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.api_core import operation_async +from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 from google.auth import credentials from google.auth.exceptions import MutualTLSChannelError @@ -170,15 +170,14 @@ def test_prediction_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -187,15 +186,14 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class() @@ -204,95 +202,185 @@ def test_prediction_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + PredictionServiceClient, + transports.PredictionServiceGrpcTransport, + "grpc", + "true", + ), + ( + PredictionServiceAsyncClient, + transports.PredictionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + PredictionServiceClient, + transports.PredictionServiceGrpcTransport, + "grpc", + "false", + ), + ( + PredictionServiceAsyncClient, + transports.PredictionServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + PredictionServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceClient), +) +@mock.patch.object( + PredictionServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(PredictionServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_prediction_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): options = client_options.ClientOptions( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=client_cert_source_callback, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", and default_client_cert_source is provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): - with mock.patch.object(transport_class, "__init__") as patched: + ssl_channel_creds = mock.Mock() with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, + "grpc.ssl_channel_credentials", return_value=ssl_channel_creds ): patched.return_value = None - client = client_class() + client = client_class(client_options=options) + + if use_client_cert_env == "false": + expected_ssl_channel_creds = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_ssl_channel_creds = ssl_channel_creds + expected_host = client.DEFAULT_MTLS_ENDPOINT + patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, + host=expected_host, scopes=None, - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=expected_ssl_channel_creds, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) - # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is - # "auto", but client_cert_source and default_client_cert_source are None. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None ): - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.ssl_credentials", + new_callable=mock.PropertyMock, + ) as ssl_credentials_mock: + if use_client_cert_env == "false": + is_mtls_mock.return_value = False + ssl_credentials_mock.return_value = None + expected_host = client.DEFAULT_ENDPOINT + expected_ssl_channel_creds = None + else: + is_mtls_mock.return_value = True + ssl_credentials_mock.return_value = mock.Mock() + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_ssl_channel_creds = ( + ssl_credentials_mock.return_value + ) + + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + ssl_channel_credentials=expected_ssl_channel_creds, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + ): + with mock.patch( + "google.auth.transport.grpc.SslCredentials.is_mtls", + new_callable=mock.PropertyMock, + ) as is_mtls_mock: + is_mtls_mock.return_value = False + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + ssl_channel_credentials=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) @pytest.mark.parametrize( @@ -319,8 +407,7 @@ def test_prediction_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -350,8 +437,7 @@ def test_prediction_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - api_mtls_endpoint=client.DEFAULT_ENDPOINT, - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -370,8 +456,7 @@ def test_prediction_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=None, + ssl_channel_credentials=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -907,6 +992,21 @@ def test_transport_get_channel(): assert channel +@pytest.mark.parametrize( + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -967,6 +1067,17 @@ def test_prediction_service_base_transport_with_credentials_file(): ) +def test_prediction_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(auth, "default") as adc, mock.patch( + "google.cloud.automl_v1beta1.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport() + adc.assert_called_once() + + def test_prediction_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(auth, "default") as adc: @@ -1015,179 +1126,110 @@ def test_prediction_service_host_with_port(): def test_prediction_service_grpc_transport_channel(): channel = grpc.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called def test_prediction_service_grpc_asyncio_transport_channel(): channel = aio.insecure_channel("http://localhost/") - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_prediction_service_grpc_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], ) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_prediction_service_grpc_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint +def test_prediction_service_transport_channel_mtls_with_client_cert_source( + transport_class, ): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - mock_cred = mock.Mock() - transport = transports.PredictionServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel @pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], ) -@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) -def test_prediction_service_grpc_asyncio_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. +def test_prediction_service_transport_channel_mtls_with_adc(transport_class): mock_ssl_cred = mock.Mock() with mock.patch.multiple( "google.auth.transport.grpc.SslCredentials", __init__=mock.Mock(return_value=None), ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): - mock_cred = mock.Mock() - transport = transports.PredictionServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - ) - assert transport.grpc_channel == mock_grpc_channel + with mock.patch.object( + transport_class, "create_channel", autospec=True + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel def test_prediction_service_grpc_lro_client(): From 04574f6f2dc638fe4e38063b20c74362d5a32128 Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 06:02:40 -0700 Subject: [PATCH 16/25] fix: switch pubsub/v1 retry config to grpc_service_config PiperOrigin-RevId: 336174031 Source-Author: Google APIs Source-Date: Thu Oct 8 15:10:41 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: bf79839b947d8b5c0f55516b963433faf23b54c4 Source-Link: https://github.com/googleapis/googleapis/commit/bf79839b947d8b5c0f55516b963433faf23b54c4 --- .../services/auto_ml/async_client.py | 24 +++++++++---------- .../services/auto_ml/transports/base.py | 24 +++++++++---------- synth.metadata | 4 ++-- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index b7a10974..55d60100 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -294,7 +294,7 @@ async def get_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -376,7 +376,7 @@ async def list_datasets( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -555,7 +555,7 @@ async def delete_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -860,7 +860,7 @@ async def get_annotation_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -948,7 +948,7 @@ async def get_table_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1030,7 +1030,7 @@ async def list_table_specs( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1200,7 +1200,7 @@ async def get_column_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1282,7 +1282,7 @@ async def list_column_specs( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1537,7 +1537,7 @@ async def get_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1619,7 +1619,7 @@ async def list_models( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1722,7 +1722,7 @@ async def delete_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -2248,7 +2248,7 @@ async def get_model_evaluation( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py index 642c9f7b..63f0601f 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py @@ -125,7 +125,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -138,7 +138,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -154,7 +154,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -173,7 +173,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -186,7 +186,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -199,7 +199,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -215,7 +215,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -228,7 +228,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -247,7 +247,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -260,7 +260,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -273,7 +273,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -300,7 +300,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, diff --git a/synth.metadata b/synth.metadata index 690d358b..223a0b11 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "d3697d47929f34c43bcc4de16c7c761a80e97cf1", - "internalRef": "333502684" + "sha": "bf79839b947d8b5c0f55516b963433faf23b54c4", + "internalRef": "336174031" } }, { From b41b0a007697f3812bc89e3d3f5bd3a25d7bba53 Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 06:02:40 -0700 Subject: [PATCH 17/25] feat: Added text extraction health care option in create model. PiperOrigin-RevId: 336180475 Source-Author: Google APIs Source-Date: Thu Oct 8 15:46:55 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: bda7ce951def5ae6e5c4258d0e569188dd4ae02b Source-Link: https://github.com/googleapis/googleapis/commit/bda7ce951def5ae6e5c4258d0e569188dd4ae02b --- google/cloud/automl_v1beta1/__init__.py | 4 +-- google/cloud/automl_v1beta1/proto/io.proto | 26 +++++++++++++++++ google/cloud/automl_v1beta1/proto/text.proto | 8 ++++- .../services/auto_ml/async_client.py | 24 +++++++-------- .../services/auto_ml/transports/base.py | 24 +++++++-------- google/cloud/automl_v1beta1/types/io.py | 29 +++++++++++++++---- google/cloud/automl_v1beta1/types/text.py | 15 +++++++++- synth.metadata | 4 +-- 8 files changed, 99 insertions(+), 35 deletions(-) diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 44f619cb..30db2703 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -149,7 +149,6 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", - "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -228,6 +227,7 @@ "OutputConfig", "PredictRequest", "PredictResponse", + "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "PredictionServiceClient", + "AutoMlClient", ) diff --git a/google/cloud/automl_v1beta1/proto/io.proto b/google/cloud/automl_v1beta1/proto/io.proto index a9979383..3d8ab45f 100644 --- a/google/cloud/automl_v1beta1/proto/io.proto +++ b/google/cloud/automl_v1beta1/proto/io.proto @@ -1015,6 +1015,32 @@ message ModelExportOutputConfig { // * For Image Classification mobile-core-ml-low-latency-1, // mobile-core-ml-versatile-1, mobile-core-ml-high-accuracy-1: // "core_ml" (default). + // + // * For Image Object Detection mobile-low-latency-1, mobile-versatile-1, + // mobile-high-accuracy-1: + // "tflite", "tf_saved_model", "tf_js". + // + // * For Video Classification cloud, + // "tf_saved_model". + // + // * For Video Object Tracking cloud, + // "tf_saved_model". + // + // * For Video Object Tracking mobile-versatile-1: + // "tflite", "edgetpu_tflite", "tf_saved_model", "docker". + // + // * For Video Object Tracking mobile-coral-versatile-1: + // "tflite", "edgetpu_tflite", "docker". + // + // * For Video Object Tracking mobile-coral-low-latency-1: + // "tflite", "edgetpu_tflite", "docker". + // + // * For Video Object Tracking mobile-jetson-versatile-1: + // "tf_saved_model", "docker". + // + // * For Tables: + // "docker". + // // Formats description: // // * tflite - Used for Android mobile devices. diff --git a/google/cloud/automl_v1beta1/proto/text.proto b/google/cloud/automl_v1beta1/proto/text.proto index f6f33185..3319a094 100644 --- a/google/cloud/automl_v1beta1/proto/text.proto +++ b/google/cloud/automl_v1beta1/proto/text.proto @@ -45,7 +45,13 @@ message TextExtractionDatasetMetadata { // Model metadata that is specific to text extraction. message TextExtractionModelMetadata { - + // Indicates the scope of model use case. + // + // * `default`: Use to train a general text extraction model. Default value. + // + // * `health_care`: Use to train a text extraction model that is tuned for + // healthcare applications. + string model_hint = 3; } // Dataset metadata for text sentiment. diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index 55d60100..b7a10974 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -294,7 +294,7 @@ async def get_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -376,7 +376,7 @@ async def list_datasets( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -555,7 +555,7 @@ async def delete_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -860,7 +860,7 @@ async def get_annotation_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -948,7 +948,7 @@ async def get_table_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1030,7 +1030,7 @@ async def list_table_specs( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1200,7 +1200,7 @@ async def get_column_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1282,7 +1282,7 @@ async def list_column_specs( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1537,7 +1537,7 @@ async def get_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1619,7 +1619,7 @@ async def list_models( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1722,7 +1722,7 @@ async def delete_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -2248,7 +2248,7 @@ async def get_model_evaluation( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py index 63f0601f..642c9f7b 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py @@ -125,7 +125,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -138,7 +138,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -154,7 +154,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -173,7 +173,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -186,7 +186,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -199,7 +199,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -215,7 +215,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -228,7 +228,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -247,7 +247,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -260,7 +260,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -273,7 +273,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -300,7 +300,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1beta1/types/io.py b/google/cloud/automl_v1beta1/types/io.py index bb91b204..5be23eb2 100644 --- a/google/cloud/automl_v1beta1/types/io.py +++ b/google/cloud/automl_v1beta1/types/io.py @@ -944,20 +944,39 @@ class ModelExportOutputConfig(proto.Message): - For Image Classification mobile-core-ml-low-latency-1, mobile-core-ml-versatile-1, mobile-core-ml-high-accuracy-1: "core_ml" (default). - Formats description: - - tflite - Used for Android mobile devices. + - For Image Object Detection mobile-low-latency-1, + mobile-versatile-1, mobile-high-accuracy-1: "tflite", + "tf_saved_model", "tf_js". + + - For Video Classification cloud, "tf_saved_model". + + - For Video Object Tracking cloud, "tf_saved_model". + + - For Video Object Tracking mobile-versatile-1: "tflite", + "edgetpu_tflite", "tf_saved_model", "docker". + + - For Video Object Tracking mobile-coral-versatile-1: + "tflite", "edgetpu_tflite", "docker". + + - For Video Object Tracking mobile-coral-low-latency-1: + "tflite", "edgetpu_tflite", "docker". + + - For Video Object Tracking mobile-jetson-versatile-1: + "tf_saved_model", "docker". + - For Tables: "docker". + + Formats description: + + - tflite - Used for Android mobile devices. - edgetpu_tflite - Used for `Edge TPU `__ devices. - - tf_saved_model - A tensorflow model in SavedModel format. - - tf_js - A `TensorFlow.js `__ model that can be used in the browser and in Node.js using JavaScript. - - docker - Used for Docker containers. Use the params field to customize the container. The container is verified to work correctly on ubuntu 16.04 operating system. See more diff --git a/google/cloud/automl_v1beta1/types/text.py b/google/cloud/automl_v1beta1/types/text.py index 8ecd3869..bc2b888c 100644 --- a/google/cloud/automl_v1beta1/types/text.py +++ b/google/cloud/automl_v1beta1/types/text.py @@ -66,7 +66,20 @@ class TextExtractionDatasetMetadata(proto.Message): class TextExtractionModelMetadata(proto.Message): - r"""Model metadata that is specific to text extraction.""" + r"""Model metadata that is specific to text extraction. + + Attributes: + model_hint (str): + Indicates the scope of model use case. + + - ``default``: Use to train a general text extraction + model. Default value. + + - ``health_care``: Use to train a text extraction model + that is tuned for healthcare applications. + """ + + model_hint = proto.Field(proto.STRING, number=3) class TextSentimentDatasetMetadata(proto.Message): diff --git a/synth.metadata b/synth.metadata index 223a0b11..948615d9 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "bf79839b947d8b5c0f55516b963433faf23b54c4", - "internalRef": "336174031" + "sha": "bda7ce951def5ae6e5c4258d0e569188dd4ae02b", + "internalRef": "336180475" } }, { From 4e751e96de358c8789a92e5c116a9ce1c3b07d5f Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 06:03:08 -0700 Subject: [PATCH 18/25] docs: fixed link from SentimentAnalysisResult PiperOrigin-RevId: 336344634 Source-Author: Google APIs Source-Date: Fri Oct 9 12:36:01 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: fd31b1600fc496d6127665d29f095371d985c637 Source-Link: https://github.com/googleapis/googleapis/commit/fd31b1600fc496d6127665d29f095371d985c637 --- google/cloud/automl_v1beta1/__init__.py | 4 ++-- synth.metadata | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 30db2703..44f619cb 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -149,6 +149,7 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", + "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -227,7 +228,6 @@ "OutputConfig", "PredictRequest", "PredictResponse", - "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "AutoMlClient", + "PredictionServiceClient", ) diff --git a/synth.metadata b/synth.metadata index 948615d9..559ac44f 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "bda7ce951def5ae6e5c4258d0e569188dd4ae02b", - "internalRef": "336180475" + "sha": "fd31b1600fc496d6127665d29f095371d985c637", + "internalRef": "336344634" } }, { From 1abfc8722d930b0e35546359a74351e65bedf630 Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 06:05:06 -0700 Subject: [PATCH 19/25] chore: upgrade to gapic-generator-python 0.35.6 PiperOrigin-RevId: 338157137 Source-Author: Google APIs Source-Date: Tue Oct 20 16:08:47 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: c7331b75b0b7bbd614373b7d37085db1c80dd4be Source-Link: https://github.com/googleapis/googleapis/commit/c7331b75b0b7bbd614373b7d37085db1c80dd4be --- .../services/auto_ml/async_client.py | 104 +- .../automl_v1/services/auto_ml/client.py | 118 +- .../services/auto_ml/transports/base.py | 18 +- .../services/auto_ml/transports/grpc.py | 14 +- .../prediction_service/async_client.py | 57 +- .../services/prediction_service/client.py | 102 +- .../prediction_service/transports/grpc.py | 14 +- google/cloud/automl_v1/types/data_items.py | 12 +- google/cloud/automl_v1/types/detection.py | 2 +- google/cloud/automl_v1/types/geometry.py | 2 +- google/cloud/automl_v1beta1/__init__.py | 4 +- .../services/auto_ml/async_client.py | 128 ++- .../automl_v1beta1/services/auto_ml/client.py | 118 +- .../services/auto_ml/transports/base.py | 24 +- .../services/auto_ml/transports/grpc.py | 14 +- .../prediction_service/async_client.py | 57 +- .../services/prediction_service/client.py | 102 +- .../prediction_service/transports/grpc.py | 14 +- .../automl_v1beta1/types/classification.py | 2 +- .../cloud/automl_v1beta1/types/data_items.py | 14 +- .../cloud/automl_v1beta1/types/data_stats.py | 4 +- .../cloud/automl_v1beta1/types/data_types.py | 2 +- .../cloud/automl_v1beta1/types/detection.py | 4 +- google/cloud/automl_v1beta1/types/geometry.py | 2 +- synth.metadata | 4 +- tests/unit/gapic/automl_v1/test_auto_ml.py | 784 ++++++++----- .../automl_v1/test_prediction_service.py | 201 +++- .../unit/gapic/automl_v1beta1/test_auto_ml.py | 1007 ++++++++++------- .../automl_v1beta1/test_prediction_service.py | 201 +++- 29 files changed, 2200 insertions(+), 929 deletions(-) diff --git a/google/cloud/automl_v1/services/auto_ml/async_client.py b/google/cloud/automl_v1/services/auto_ml/async_client.py index 23d7b118..254f5cc5 100644 --- a/google/cloud/automl_v1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1/services/auto_ml/async_client.py @@ -79,14 +79,46 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT + annotation_spec_path = staticmethod(AutoMlClient.annotation_spec_path) + parse_annotation_spec_path = staticmethod(AutoMlClient.parse_annotation_spec_path) dataset_path = staticmethod(AutoMlClient.dataset_path) parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) model_path = staticmethod(AutoMlClient.model_path) parse_model_path = staticmethod(AutoMlClient.parse_model_path) + model_evaluation_path = staticmethod(AutoMlClient.model_evaluation_path) + parse_model_evaluation_path = staticmethod(AutoMlClient.parse_model_evaluation_path) + + common_billing_account_path = staticmethod(AutoMlClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod( + AutoMlClient.parse_common_billing_account_path + ) + + common_folder_path = staticmethod(AutoMlClient.common_folder_path) + parse_common_folder_path = staticmethod(AutoMlClient.parse_common_folder_path) + + common_organization_path = staticmethod(AutoMlClient.common_organization_path) + parse_common_organization_path = staticmethod( + AutoMlClient.parse_common_organization_path + ) + + common_project_path = staticmethod(AutoMlClient.common_project_path) + parse_common_project_path = staticmethod(AutoMlClient.parse_common_project_path) + + common_location_path = staticmethod(AutoMlClient.common_location_path) + parse_common_location_path = staticmethod(AutoMlClient.parse_common_location_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file + @property + def transport(self) -> AutoMlTransport: + """Return the transport used by the client instance. + + Returns: + AutoMlTransport: The transport used by the client instance. + """ + return self._client.transport + get_transport_class = functools.partial( type(AutoMlClient).get_transport_class, type(AutoMlClient) ) @@ -187,7 +219,8 @@ async def create_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent, dataset]): + has_flattened_params = any([parent, dataset]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -270,7 +303,8 @@ async def get_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -293,7 +327,7 @@ async def get_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -352,7 +386,8 @@ async def list_datasets( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent]): + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -375,7 +410,7 @@ async def list_datasets( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -446,7 +481,8 @@ async def update_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([dataset, update_mask]): + has_flattened_params = any([dataset, update_mask]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -540,7 +576,8 @@ async def delete_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -563,7 +600,7 @@ async def delete_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -660,7 +697,8 @@ async def import_data( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, input_config]): + has_flattened_params = any([name, input_config]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -766,7 +804,8 @@ async def export_data( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, output_config]): + has_flattened_params = any([name, output_config]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -845,7 +884,8 @@ async def get_annotation_spec( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -868,7 +908,7 @@ async def get_annotation_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -938,7 +978,8 @@ async def create_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent, model]): + has_flattened_params = any([parent, model]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1018,7 +1059,8 @@ async def get_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1041,7 +1083,7 @@ async def get_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1100,7 +1142,8 @@ async def list_models( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent]): + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1123,7 +1166,7 @@ async def list_models( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1203,7 +1246,8 @@ async def delete_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1226,7 +1270,7 @@ async def delete_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1297,7 +1341,8 @@ async def update_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([model, update_mask]): + has_flattened_params = any([model, update_mask]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1401,7 +1446,8 @@ async def deploy_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1503,7 +1549,8 @@ async def undeploy_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1613,7 +1660,8 @@ async def export_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, output_config]): + has_flattened_params = any([name, output_config]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1692,7 +1740,8 @@ async def get_model_evaluation( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1715,7 +1764,7 @@ async def get_model_evaluation( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1795,7 +1844,8 @@ async def list_model_evaluations( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent, filter]): + has_flattened_params = any([parent, filter]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1820,7 +1870,7 @@ async def list_model_evaluations( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1/services/auto_ml/client.py b/google/cloud/automl_v1/services/auto_ml/client.py index 3765ac0b..0b860787 100644 --- a/google/cloud/automl_v1/services/auto_ml/client.py +++ b/google/cloud/automl_v1/services/auto_ml/client.py @@ -163,6 +163,36 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @property + def transport(self) -> AutoMlTransport: + """Return the transport used by the client instance. + + Returns: + AutoMlTransport: The transport used by the client instance. + """ + return self._transport + + @staticmethod + def annotation_spec_path( + project: str, location: str, dataset: str, annotation_spec: str, + ) -> str: + """Return a fully-qualified annotation_spec string.""" + return "projects/{project}/locations/{location}/datasets/{dataset}/annotationSpecs/{annotation_spec}".format( + project=project, + location=location, + dataset=dataset, + annotation_spec=annotation_spec, + ) + + @staticmethod + def parse_annotation_spec_path(path: str) -> Dict[str, str]: + """Parse a annotation_spec path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/datasets/(?P.+?)/annotationSpecs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def dataset_path(project: str, location: str, dataset: str,) -> str: """Return a fully-qualified dataset string.""" @@ -195,6 +225,86 @@ def parse_model_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def model_evaluation_path( + project: str, location: str, model: str, model_evaluation: str, + ) -> str: + """Return a fully-qualified model_evaluation string.""" + return "projects/{project}/locations/{location}/models/{model}/modelEvaluations/{model_evaluation}".format( + project=project, + location=location, + model=model, + model_evaluation=model_evaluation, + ) + + @staticmethod + def parse_model_evaluation_path(path: str) -> Dict[str, str]: + """Parse a model_evaluation path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/models/(?P.+?)/modelEvaluations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Return a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Return a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Return a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Return a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Return a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + def __init__( self, *, @@ -230,10 +340,10 @@ def __init__( not provided, the default SSL client certificate will be used if present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: diff --git a/google/cloud/automl_v1/services/auto_ml/transports/base.py b/google/cloud/automl_v1/services/auto_ml/transports/base.py index b1e12781..7deddee8 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/base.py @@ -122,7 +122,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -135,7 +135,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -151,7 +151,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -170,7 +170,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -186,7 +186,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -199,7 +199,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -212,7 +212,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -237,7 +237,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -250,7 +250,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py index b957e5cd..cc627573 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py @@ -111,10 +111,10 @@ def __init__( for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -243,12 +243,8 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. + """Return the channel designed to connect to this service. """ - # Return the channel from cache. return self._grpc_channel @property diff --git a/google/cloud/automl_v1/services/prediction_service/async_client.py b/google/cloud/automl_v1/services/prediction_service/async_client.py index d77836a0..7f922fb3 100644 --- a/google/cloud/automl_v1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1/services/prediction_service/async_client.py @@ -53,9 +53,50 @@ class PredictionServiceAsyncClient: DEFAULT_ENDPOINT = PredictionServiceClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = PredictionServiceClient.DEFAULT_MTLS_ENDPOINT + model_path = staticmethod(PredictionServiceClient.model_path) + parse_model_path = staticmethod(PredictionServiceClient.parse_model_path) + + common_billing_account_path = staticmethod( + PredictionServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + PredictionServiceClient.parse_common_billing_account_path + ) + + common_folder_path = staticmethod(PredictionServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + PredictionServiceClient.parse_common_folder_path + ) + + common_organization_path = staticmethod( + PredictionServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + PredictionServiceClient.parse_common_organization_path + ) + + common_project_path = staticmethod(PredictionServiceClient.common_project_path) + parse_common_project_path = staticmethod( + PredictionServiceClient.parse_common_project_path + ) + + common_location_path = staticmethod(PredictionServiceClient.common_location_path) + parse_common_location_path = staticmethod( + PredictionServiceClient.parse_common_location_path + ) + from_service_account_file = PredictionServiceClient.from_service_account_file from_service_account_json = from_service_account_file + @property + def transport(self) -> PredictionServiceTransport: + """Return the transport used by the client instance. + + Returns: + PredictionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + get_transport_class = functools.partial( type(PredictionServiceClient).get_transport_class, type(PredictionServiceClient) ) @@ -225,7 +266,8 @@ async def predict( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, payload, params]): + has_flattened_params = any([name, payload, params]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -240,8 +282,9 @@ async def predict( request.name = name if payload is not None: request.payload = payload - if params is not None: - request.params = params + + if params: + request.params.update(params) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -429,7 +472,8 @@ async def batch_predict( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, input_config, output_config, params]): + has_flattened_params = any([name, input_config, output_config, params]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -446,8 +490,9 @@ async def batch_predict( request.input_config = input_config if output_config is not None: request.output_config = output_config - if params is not None: - request.params = params + + if params: + request.params.update(params) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/automl_v1/services/prediction_service/client.py b/google/cloud/automl_v1/services/prediction_service/client.py index d2c1971a..a56b5a30 100644 --- a/google/cloud/automl_v1/services/prediction_service/client.py +++ b/google/cloud/automl_v1/services/prediction_service/client.py @@ -141,6 +141,90 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @property + def transport(self) -> PredictionServiceTransport: + """Return the transport used by the client instance. + + Returns: + PredictionServiceTransport: The transport used by the client instance. + """ + return self._transport + + @staticmethod + def model_path(project: str, location: str, model: str,) -> str: + """Return a fully-qualified model string.""" + return "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, + ) + + @staticmethod + def parse_model_path(path: str) -> Dict[str, str]: + """Parse a model path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/models/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Return a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Return a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Return a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Return a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Return a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + def __init__( self, *, @@ -176,10 +260,10 @@ def __init__( not provided, the default SSL client certificate will be used if present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -396,8 +480,9 @@ def predict( request.name = name if payload is not None: request.payload = payload - if params is not None: - request.params = params + + if params: + request.params.update(params) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -604,8 +689,9 @@ def batch_predict( request.input_config = input_config if output_config is not None: request.output_config = output_config - if params is not None: - request.params = params + + if params: + request.params.update(params) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py index 9a2c8e9b..17c81f49 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py @@ -94,10 +94,10 @@ def __init__( for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -226,12 +226,8 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. + """Return the channel designed to connect to this service. """ - # Return the channel from cache. return self._grpc_channel @property diff --git a/google/cloud/automl_v1/types/data_items.py b/google/cloud/automl_v1/types/data_items.py index 51ccc477..554ed762 100644 --- a/google/cloud/automl_v1/types/data_items.py +++ b/google/cloud/automl_v1/types/data_items.py @@ -186,12 +186,12 @@ class TextSegmentType(proto.Enum): input_config = proto.Field(proto.MESSAGE, number=1, message=io.DocumentInputConfig,) - document_text = proto.Field(proto.MESSAGE, number=2, message=TextSnippet,) + document_text = proto.Field(proto.MESSAGE, number=2, message="TextSnippet",) layout = proto.RepeatedField(proto.MESSAGE, number=3, message=Layout,) document_dimensions = proto.Field( - proto.MESSAGE, number=4, message=DocumentDimensions, + proto.MESSAGE, number=4, message="DocumentDimensions", ) page_count = proto.Field(proto.INT32, number=5) @@ -209,13 +209,15 @@ class ExamplePayload(proto.Message): Example document. """ - image = proto.Field(proto.MESSAGE, number=1, oneof="payload", message=Image,) + image = proto.Field(proto.MESSAGE, number=1, oneof="payload", message="Image",) text_snippet = proto.Field( - proto.MESSAGE, number=2, oneof="payload", message=TextSnippet, + proto.MESSAGE, number=2, oneof="payload", message="TextSnippet", ) - document = proto.Field(proto.MESSAGE, number=4, oneof="payload", message=Document,) + document = proto.Field( + proto.MESSAGE, number=4, oneof="payload", message="Document", + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/automl_v1/types/detection.py b/google/cloud/automl_v1/types/detection.py index 6eab690c..69ca1d54 100644 --- a/google/cloud/automl_v1/types/detection.py +++ b/google/cloud/automl_v1/types/detection.py @@ -128,7 +128,7 @@ class ImageObjectDetectionEvaluationMetrics(proto.Message): evaluated_bounding_box_count = proto.Field(proto.INT32, number=1) bounding_box_metrics_entries = proto.RepeatedField( - proto.MESSAGE, number=2, message=BoundingBoxMetricsEntry, + proto.MESSAGE, number=2, message="BoundingBoxMetricsEntry", ) bounding_box_mean_average_precision = proto.Field(proto.FLOAT, number=3) diff --git a/google/cloud/automl_v1/types/geometry.py b/google/cloud/automl_v1/types/geometry.py index f459ca52..07c22dd9 100644 --- a/google/cloud/automl_v1/types/geometry.py +++ b/google/cloud/automl_v1/types/geometry.py @@ -55,7 +55,7 @@ class BoundingPoly(proto.Message): """ normalized_vertices = proto.RepeatedField( - proto.MESSAGE, number=2, message=NormalizedVertex, + proto.MESSAGE, number=2, message="NormalizedVertex", ) diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 44f619cb..30db2703 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -149,7 +149,6 @@ "AnnotationPayload", "AnnotationSpec", "ArrayStats", - "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -228,6 +227,7 @@ "OutputConfig", "PredictRequest", "PredictResponse", + "PredictionServiceClient", "RegressionEvaluationMetrics", "Row", "StringStats", @@ -269,5 +269,5 @@ "VideoObjectTrackingDatasetMetadata", "VideoObjectTrackingEvaluationMetrics", "VideoObjectTrackingModelMetadata", - "PredictionServiceClient", + "AutoMlClient", ) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index b7a10974..cd2c4388 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -87,18 +87,50 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT + annotation_spec_path = staticmethod(AutoMlClient.annotation_spec_path) + parse_annotation_spec_path = staticmethod(AutoMlClient.parse_annotation_spec_path) column_spec_path = staticmethod(AutoMlClient.column_spec_path) parse_column_spec_path = staticmethod(AutoMlClient.parse_column_spec_path) dataset_path = staticmethod(AutoMlClient.dataset_path) parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) model_path = staticmethod(AutoMlClient.model_path) parse_model_path = staticmethod(AutoMlClient.parse_model_path) + model_evaluation_path = staticmethod(AutoMlClient.model_evaluation_path) + parse_model_evaluation_path = staticmethod(AutoMlClient.parse_model_evaluation_path) table_spec_path = staticmethod(AutoMlClient.table_spec_path) parse_table_spec_path = staticmethod(AutoMlClient.parse_table_spec_path) + common_billing_account_path = staticmethod(AutoMlClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod( + AutoMlClient.parse_common_billing_account_path + ) + + common_folder_path = staticmethod(AutoMlClient.common_folder_path) + parse_common_folder_path = staticmethod(AutoMlClient.parse_common_folder_path) + + common_organization_path = staticmethod(AutoMlClient.common_organization_path) + parse_common_organization_path = staticmethod( + AutoMlClient.parse_common_organization_path + ) + + common_project_path = staticmethod(AutoMlClient.common_project_path) + parse_common_project_path = staticmethod(AutoMlClient.parse_common_project_path) + + common_location_path = staticmethod(AutoMlClient.common_location_path) + parse_common_location_path = staticmethod(AutoMlClient.parse_common_location_path) + from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file + @property + def transport(self) -> AutoMlTransport: + """Return the transport used by the client instance. + + Returns: + AutoMlTransport: The transport used by the client instance. + """ + return self._client.transport + get_transport_class = functools.partial( type(AutoMlClient).get_transport_class, type(AutoMlClient) ) @@ -196,7 +228,8 @@ async def create_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent, dataset]): + has_flattened_params = any([parent, dataset]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -271,7 +304,8 @@ async def get_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -294,7 +328,7 @@ async def get_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -353,7 +387,8 @@ async def list_datasets( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent]): + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -376,7 +411,7 @@ async def list_datasets( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -440,7 +475,8 @@ async def update_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([dataset]): + has_flattened_params = any([dataset]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -532,7 +568,8 @@ async def delete_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -555,7 +592,7 @@ async def delete_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -652,7 +689,8 @@ async def import_data( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, input_config]): + has_flattened_params = any([name, input_config]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -758,7 +796,8 @@ async def export_data( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, output_config]): + has_flattened_params = any([name, output_config]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -837,7 +876,8 @@ async def get_annotation_spec( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -860,7 +900,7 @@ async def get_annotation_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -925,7 +965,8 @@ async def get_table_spec( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -948,7 +989,7 @@ async def get_table_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1007,7 +1048,8 @@ async def list_table_specs( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent]): + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1030,7 +1072,7 @@ async def list_table_specs( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1101,7 +1143,8 @@ async def update_table_spec( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([table_spec]): + has_flattened_params = any([table_spec]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1177,7 +1220,8 @@ async def get_column_spec( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1200,7 +1244,7 @@ async def get_column_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1259,7 +1303,8 @@ async def list_column_specs( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent]): + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1282,7 +1327,7 @@ async def list_column_specs( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1347,7 +1392,8 @@ async def update_column_spec( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([column_spec]): + has_flattened_params = any([column_spec]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1434,7 +1480,8 @@ async def create_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent, model]): + has_flattened_params = any([parent, model]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1514,7 +1561,8 @@ async def get_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1537,7 +1585,7 @@ async def get_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1596,7 +1644,8 @@ async def list_models( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent]): + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1619,7 +1668,7 @@ async def list_models( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1699,7 +1748,8 @@ async def delete_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1722,7 +1772,7 @@ async def delete_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -1815,7 +1865,8 @@ async def deploy_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1917,7 +1968,8 @@ async def undeploy_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -2028,7 +2080,8 @@ async def export_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, output_config]): + has_flattened_params = any([name, output_config]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -2146,7 +2199,8 @@ async def export_evaluated_examples( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, output_config]): + has_flattened_params = any([name, output_config]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -2225,7 +2279,8 @@ async def get_model_evaluation( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + has_flattened_params = any([name]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -2248,7 +2303,7 @@ async def get_model_evaluation( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -2310,7 +2365,8 @@ async def list_model_evaluations( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent]): + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." diff --git a/google/cloud/automl_v1beta1/services/auto_ml/client.py b/google/cloud/automl_v1beta1/services/auto_ml/client.py index 6ae4f4c2..a930910e 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/client.py @@ -171,6 +171,36 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @property + def transport(self) -> AutoMlTransport: + """Return the transport used by the client instance. + + Returns: + AutoMlTransport: The transport used by the client instance. + """ + return self._transport + + @staticmethod + def annotation_spec_path( + project: str, location: str, dataset: str, annotation_spec: str, + ) -> str: + """Return a fully-qualified annotation_spec string.""" + return "projects/{project}/locations/{location}/datasets/{dataset}/annotationSpecs/{annotation_spec}".format( + project=project, + location=location, + dataset=dataset, + annotation_spec=annotation_spec, + ) + + @staticmethod + def parse_annotation_spec_path(path: str) -> Dict[str, str]: + """Parse a annotation_spec path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/datasets/(?P.+?)/annotationSpecs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def column_spec_path( project: str, location: str, dataset: str, table_spec: str, column_spec: str, @@ -225,6 +255,27 @@ def parse_model_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def model_evaluation_path( + project: str, location: str, model: str, model_evaluation: str, + ) -> str: + """Return a fully-qualified model_evaluation string.""" + return "projects/{project}/locations/{location}/models/{model}/modelEvaluations/{model_evaluation}".format( + project=project, + location=location, + model=model, + model_evaluation=model_evaluation, + ) + + @staticmethod + def parse_model_evaluation_path(path: str) -> Dict[str, str]: + """Parse a model_evaluation path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/models/(?P.+?)/modelEvaluations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def table_spec_path( project: str, location: str, dataset: str, table_spec: str, @@ -243,6 +294,65 @@ def parse_table_spec_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Return a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Return a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Return a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Return a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Return a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + def __init__( self, *, @@ -278,10 +388,10 @@ def __init__( not provided, the default SSL client certificate will be used if present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py index 642c9f7b..63f0601f 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py @@ -125,7 +125,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -138,7 +138,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -154,7 +154,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -173,7 +173,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -186,7 +186,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -199,7 +199,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -215,7 +215,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -228,7 +228,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -247,7 +247,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -260,7 +260,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -273,7 +273,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, @@ -300,7 +300,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py index a8cb2fd7..9c8c1580 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py @@ -114,10 +114,10 @@ def __init__( for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -246,12 +246,8 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. + """Return the channel designed to connect to this service. """ - # Return the channel from cache. return self._grpc_channel @property diff --git a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py index c204325b..b1eadd8e 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py @@ -53,9 +53,50 @@ class PredictionServiceAsyncClient: DEFAULT_ENDPOINT = PredictionServiceClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = PredictionServiceClient.DEFAULT_MTLS_ENDPOINT + model_path = staticmethod(PredictionServiceClient.model_path) + parse_model_path = staticmethod(PredictionServiceClient.parse_model_path) + + common_billing_account_path = staticmethod( + PredictionServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + PredictionServiceClient.parse_common_billing_account_path + ) + + common_folder_path = staticmethod(PredictionServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + PredictionServiceClient.parse_common_folder_path + ) + + common_organization_path = staticmethod( + PredictionServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + PredictionServiceClient.parse_common_organization_path + ) + + common_project_path = staticmethod(PredictionServiceClient.common_project_path) + parse_common_project_path = staticmethod( + PredictionServiceClient.parse_common_project_path + ) + + common_location_path = staticmethod(PredictionServiceClient.common_location_path) + parse_common_location_path = staticmethod( + PredictionServiceClient.parse_common_location_path + ) + from_service_account_file = PredictionServiceClient.from_service_account_file from_service_account_json = from_service_account_file + @property + def transport(self) -> PredictionServiceTransport: + """Return the transport used by the client instance. + + Returns: + PredictionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + get_transport_class = functools.partial( type(PredictionServiceClient).get_transport_class, type(PredictionServiceClient) ) @@ -201,7 +242,8 @@ async def predict( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, payload, params]): + has_flattened_params = any([name, payload, params]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -216,8 +258,9 @@ async def predict( request.name = name if payload is not None: request.payload = payload - if params is not None: - request.params = params + + if params: + request.params.update(params) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -401,7 +444,8 @@ async def batch_predict( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, input_config, output_config, params]): + has_flattened_params = any([name, input_config, output_config, params]) + if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -418,8 +462,9 @@ async def batch_predict( request.input_config = input_config if output_config is not None: request.output_config = output_config - if params is not None: - request.params = params + + if params: + request.params.update(params) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/automl_v1beta1/services/prediction_service/client.py b/google/cloud/automl_v1beta1/services/prediction_service/client.py index 78ec510c..7508e83a 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/client.py @@ -141,6 +141,90 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @property + def transport(self) -> PredictionServiceTransport: + """Return the transport used by the client instance. + + Returns: + PredictionServiceTransport: The transport used by the client instance. + """ + return self._transport + + @staticmethod + def model_path(project: str, location: str, model: str,) -> str: + """Return a fully-qualified model string.""" + return "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, + ) + + @staticmethod + def parse_model_path(path: str) -> Dict[str, str]: + """Parse a model path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/models/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Return a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str,) -> str: + """Return a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder,) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str,) -> str: + """Return a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization,) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str,) -> str: + """Return a fully-qualified project string.""" + return "projects/{project}".format(project=project,) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str,) -> str: + """Return a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + def __init__( self, *, @@ -176,10 +260,10 @@ def __init__( not provided, the default SSL client certificate will be used if present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -372,8 +456,9 @@ def predict( request.name = name if payload is not None: request.payload = payload - if params is not None: - request.params = params + + if params: + request.params.update(params) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -576,8 +661,9 @@ def batch_predict( request.input_config = input_config if output_config is not None: request.output_config = output_config - if params is not None: - request.params = params + + if params: + request.params.update(params) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py index 3c484247..8d8225e1 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py @@ -94,10 +94,10 @@ def __init__( for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -226,12 +226,8 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. + """Return the channel designed to connect to this service. """ - # Return the channel from cache. return self._grpc_channel @property diff --git a/google/cloud/automl_v1beta1/types/classification.py b/google/cloud/automl_v1beta1/types/classification.py index 4b5e5a2a..b9f21ba3 100644 --- a/google/cloud/automl_v1beta1/types/classification.py +++ b/google/cloud/automl_v1beta1/types/classification.py @@ -99,7 +99,7 @@ class VideoClassificationAnnotation(proto.Message): type_ = proto.Field(proto.STRING, number=1) classification_annotation = proto.Field( - proto.MESSAGE, number=2, message=ClassificationAnnotation, + proto.MESSAGE, number=2, message="ClassificationAnnotation", ) time_segment = proto.Field(proto.MESSAGE, number=3, message=temporal.TimeSegment,) diff --git a/google/cloud/automl_v1beta1/types/data_items.py b/google/cloud/automl_v1beta1/types/data_items.py index 4e0037b0..eff58bee 100644 --- a/google/cloud/automl_v1beta1/types/data_items.py +++ b/google/cloud/automl_v1beta1/types/data_items.py @@ -195,12 +195,12 @@ class TextSegmentType(proto.Enum): input_config = proto.Field(proto.MESSAGE, number=1, message=io.DocumentInputConfig,) - document_text = proto.Field(proto.MESSAGE, number=2, message=TextSnippet,) + document_text = proto.Field(proto.MESSAGE, number=2, message="TextSnippet",) layout = proto.RepeatedField(proto.MESSAGE, number=3, message=Layout,) document_dimensions = proto.Field( - proto.MESSAGE, number=4, message=DocumentDimensions, + proto.MESSAGE, number=4, message="DocumentDimensions", ) page_count = proto.Field(proto.INT32, number=5) @@ -247,15 +247,17 @@ class ExamplePayload(proto.Message): Example relational table row. """ - image = proto.Field(proto.MESSAGE, number=1, oneof="payload", message=Image,) + image = proto.Field(proto.MESSAGE, number=1, oneof="payload", message="Image",) text_snippet = proto.Field( - proto.MESSAGE, number=2, oneof="payload", message=TextSnippet, + proto.MESSAGE, number=2, oneof="payload", message="TextSnippet", ) - document = proto.Field(proto.MESSAGE, number=4, oneof="payload", message=Document,) + document = proto.Field( + proto.MESSAGE, number=4, oneof="payload", message="Document", + ) - row = proto.Field(proto.MESSAGE, number=3, oneof="payload", message=Row,) + row = proto.Field(proto.MESSAGE, number=3, oneof="payload", message="Row",) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/automl_v1beta1/types/data_stats.py b/google/cloud/automl_v1beta1/types/data_stats.py index 4405185f..75a9dc38 100644 --- a/google/cloud/automl_v1beta1/types/data_stats.py +++ b/google/cloud/automl_v1beta1/types/data_stats.py @@ -210,7 +210,7 @@ class ArrayStats(proto.Message): depends on the element type of the array. """ - member_stats = proto.Field(proto.MESSAGE, number=2, message=DataStats,) + member_stats = proto.Field(proto.MESSAGE, number=2, message="DataStats",) class StructStats(proto.Message): @@ -224,7 +224,7 @@ class StructStats(proto.Message): """ field_stats = proto.MapField( - proto.STRING, proto.MESSAGE, number=1, message=DataStats, + proto.STRING, proto.MESSAGE, number=1, message="DataStats", ) diff --git a/google/cloud/automl_v1beta1/types/data_types.py b/google/cloud/automl_v1beta1/types/data_types.py index e2a3152e..6faa598b 100644 --- a/google/cloud/automl_v1beta1/types/data_types.py +++ b/google/cloud/automl_v1beta1/types/data_types.py @@ -105,7 +105,7 @@ class StructType(proto.Message): mutable. """ - fields = proto.MapField(proto.STRING, proto.MESSAGE, number=1, message=DataType,) + fields = proto.MapField(proto.STRING, proto.MESSAGE, number=1, message="DataType",) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/automl_v1beta1/types/detection.py b/google/cloud/automl_v1beta1/types/detection.py index 3f3339ab..c14a1cb5 100644 --- a/google/cloud/automl_v1beta1/types/detection.py +++ b/google/cloud/automl_v1beta1/types/detection.py @@ -171,7 +171,7 @@ class ImageObjectDetectionEvaluationMetrics(proto.Message): evaluated_bounding_box_count = proto.Field(proto.INT32, number=1) bounding_box_metrics_entries = proto.RepeatedField( - proto.MESSAGE, number=2, message=BoundingBoxMetricsEntry, + proto.MESSAGE, number=2, message="BoundingBoxMetricsEntry", ) bounding_box_mean_average_precision = proto.Field(proto.FLOAT, number=3) @@ -208,7 +208,7 @@ class VideoObjectTrackingEvaluationMetrics(proto.Message): evaluated_bounding_box_count = proto.Field(proto.INT32, number=2) bounding_box_metrics_entries = proto.RepeatedField( - proto.MESSAGE, number=4, message=BoundingBoxMetricsEntry, + proto.MESSAGE, number=4, message="BoundingBoxMetricsEntry", ) bounding_box_mean_average_precision = proto.Field(proto.FLOAT, number=6) diff --git a/google/cloud/automl_v1beta1/types/geometry.py b/google/cloud/automl_v1beta1/types/geometry.py index 7a463691..f64a477f 100644 --- a/google/cloud/automl_v1beta1/types/geometry.py +++ b/google/cloud/automl_v1beta1/types/geometry.py @@ -56,7 +56,7 @@ class BoundingPoly(proto.Message): """ normalized_vertices = proto.RepeatedField( - proto.MESSAGE, number=2, message=NormalizedVertex, + proto.MESSAGE, number=2, message="NormalizedVertex", ) diff --git a/synth.metadata b/synth.metadata index 559ac44f..51c12757 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "fd31b1600fc496d6127665d29f095371d985c637", - "internalRef": "336344634" + "sha": "c7331b75b0b7bbd614373b7d37085db1c80dd4be", + "internalRef": "338157137" } }, { diff --git a/tests/unit/gapic/automl_v1/test_auto_ml.py b/tests/unit/gapic/automl_v1/test_auto_ml.py index a11480cd..85e68e74 100644 --- a/tests/unit/gapic/automl_v1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1/test_auto_ml.py @@ -107,12 +107,12 @@ def test_auto_ml_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds - assert client._transport._host == "automl.googleapis.com:443" + assert client.transport._host == "automl.googleapis.com:443" def test_auto_ml_client_get_transport_class(): @@ -438,7 +438,7 @@ def test_create_dataset( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -459,19 +459,19 @@ def test_create_dataset_from_dict(): @pytest.mark.asyncio -async def test_create_dataset_async(transport: str = "grpc_asyncio"): +async def test_create_dataset_async( + transport: str = "grpc_asyncio", request_type=service.CreateDatasetRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.CreateDatasetRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -483,12 +483,17 @@ async def test_create_dataset_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.CreateDatasetRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_create_dataset_async_from_dict(): + await test_create_dataset_async(request_type=dict) + + def test_create_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -498,7 +503,7 @@ def test_create_dataset_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.create_dataset(request) @@ -523,9 +528,7 @@ async def test_create_dataset_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -546,7 +549,7 @@ def test_create_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -597,9 +600,7 @@ async def test_create_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -659,7 +660,7 @@ def test_get_dataset(transport: str = "grpc", request_type=service.GetDatasetReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = dataset.Dataset( name="name_value", @@ -681,6 +682,7 @@ def test_get_dataset(transport: str = "grpc", request_type=service.GetDatasetReq assert args[0] == service.GetDatasetRequest() # Establish that the response is the type that we expect. + assert isinstance(response, dataset.Dataset) assert response.name == "name_value" @@ -699,19 +701,19 @@ def test_get_dataset_from_dict(): @pytest.mark.asyncio -async def test_get_dataset_async(transport: str = "grpc_asyncio"): +async def test_get_dataset_async( + transport: str = "grpc_asyncio", request_type=service.GetDatasetRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.GetDatasetRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( dataset.Dataset( @@ -729,7 +731,7 @@ async def test_get_dataset_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.GetDatasetRequest() # Establish that the response is the type that we expect. assert isinstance(response, dataset.Dataset) @@ -745,6 +747,11 @@ async def test_get_dataset_async(transport: str = "grpc_asyncio"): assert response.etag == "etag_value" +@pytest.mark.asyncio +async def test_get_dataset_async_from_dict(): + await test_get_dataset_async(request_type=dict) + + def test_get_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -754,7 +761,7 @@ def test_get_dataset_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: call.return_value = dataset.Dataset() client.get_dataset(request) @@ -779,9 +786,7 @@ async def test_get_dataset_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(dataset.Dataset()) await client.get_dataset(request) @@ -800,7 +805,7 @@ def test_get_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = dataset.Dataset() @@ -832,9 +837,7 @@ async def test_get_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = dataset.Dataset() @@ -875,7 +878,7 @@ def test_list_datasets( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListDatasetsResponse( next_page_token="next_page_token_value", @@ -890,6 +893,7 @@ def test_list_datasets( assert args[0] == service.ListDatasetsRequest() # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDatasetsPager) assert response.next_page_token == "next_page_token_value" @@ -900,19 +904,19 @@ def test_list_datasets_from_dict(): @pytest.mark.asyncio -async def test_list_datasets_async(transport: str = "grpc_asyncio"): +async def test_list_datasets_async( + transport: str = "grpc_asyncio", request_type=service.ListDatasetsRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ListDatasetsRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_datasets), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListDatasetsResponse(next_page_token="next_page_token_value",) @@ -924,7 +928,7 @@ async def test_list_datasets_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ListDatasetsRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListDatasetsAsyncPager) @@ -932,6 +936,11 @@ async def test_list_datasets_async(transport: str = "grpc_asyncio"): assert response.next_page_token == "next_page_token_value" +@pytest.mark.asyncio +async def test_list_datasets_async_from_dict(): + await test_list_datasets_async(request_type=dict) + + def test_list_datasets_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -941,7 +950,7 @@ def test_list_datasets_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: call.return_value = service.ListDatasetsResponse() client.list_datasets(request) @@ -966,9 +975,7 @@ async def test_list_datasets_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_datasets), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListDatasetsResponse() ) @@ -989,7 +996,7 @@ def test_list_datasets_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListDatasetsResponse() @@ -1021,9 +1028,7 @@ async def test_list_datasets_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_datasets), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListDatasetsResponse() @@ -1058,7 +1063,7 @@ def test_list_datasets_pager(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListDatasetsResponse( @@ -1092,7 +1097,7 @@ def test_list_datasets_pages(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListDatasetsResponse( @@ -1119,9 +1124,7 @@ async def test_list_datasets_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_datasets), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_datasets), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -1154,9 +1157,7 @@ async def test_list_datasets_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_datasets), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_datasets), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -1192,7 +1193,7 @@ def test_update_dataset( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset( name="name_value", @@ -1214,6 +1215,7 @@ def test_update_dataset( assert args[0] == service.UpdateDatasetRequest() # Establish that the response is the type that we expect. + assert isinstance(response, gca_dataset.Dataset) assert response.name == "name_value" @@ -1232,19 +1234,19 @@ def test_update_dataset_from_dict(): @pytest.mark.asyncio -async def test_update_dataset_async(transport: str = "grpc_asyncio"): +async def test_update_dataset_async( + transport: str = "grpc_asyncio", request_type=service.UpdateDatasetRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.UpdateDatasetRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( gca_dataset.Dataset( @@ -1262,7 +1264,7 @@ async def test_update_dataset_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.UpdateDatasetRequest() # Establish that the response is the type that we expect. assert isinstance(response, gca_dataset.Dataset) @@ -1278,6 +1280,11 @@ async def test_update_dataset_async(transport: str = "grpc_asyncio"): assert response.etag == "etag_value" +@pytest.mark.asyncio +async def test_update_dataset_async_from_dict(): + await test_update_dataset_async(request_type=dict) + + def test_update_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1287,7 +1294,7 @@ def test_update_dataset_field_headers(): request.dataset.name = "dataset.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: call.return_value = gca_dataset.Dataset() client.update_dataset(request) @@ -1314,9 +1321,7 @@ async def test_update_dataset_field_headers_async(): request.dataset.name = "dataset.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gca_dataset.Dataset()) await client.update_dataset(request) @@ -1337,7 +1342,7 @@ def test_update_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset() @@ -1388,9 +1393,7 @@ async def test_update_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset() @@ -1450,7 +1453,7 @@ def test_delete_dataset( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -1471,19 +1474,19 @@ def test_delete_dataset_from_dict(): @pytest.mark.asyncio -async def test_delete_dataset_async(transport: str = "grpc_asyncio"): +async def test_delete_dataset_async( + transport: str = "grpc_asyncio", request_type=service.DeleteDatasetRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.DeleteDatasetRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -1495,12 +1498,17 @@ async def test_delete_dataset_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.DeleteDatasetRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_delete_dataset_async_from_dict(): + await test_delete_dataset_async(request_type=dict) + + def test_delete_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1510,7 +1518,7 @@ def test_delete_dataset_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.delete_dataset(request) @@ -1535,9 +1543,7 @@ async def test_delete_dataset_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -1558,7 +1564,7 @@ def test_delete_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1590,9 +1596,7 @@ async def test_delete_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1633,7 +1637,7 @@ def test_import_data(transport: str = "grpc", request_type=service.ImportDataReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.import_data), "__call__") as call: + with mock.patch.object(type(client.transport.import_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -1654,19 +1658,19 @@ def test_import_data_from_dict(): @pytest.mark.asyncio -async def test_import_data_async(transport: str = "grpc_asyncio"): +async def test_import_data_async( + transport: str = "grpc_asyncio", request_type=service.ImportDataRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ImportDataRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.import_data), "__call__" - ) as call: + with mock.patch.object(type(client.transport.import_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -1678,12 +1682,17 @@ async def test_import_data_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ImportDataRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_import_data_async_from_dict(): + await test_import_data_async(request_type=dict) + + def test_import_data_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1693,7 +1702,7 @@ def test_import_data_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.import_data), "__call__") as call: + with mock.patch.object(type(client.transport.import_data), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.import_data(request) @@ -1718,9 +1727,7 @@ async def test_import_data_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.import_data), "__call__" - ) as call: + with mock.patch.object(type(client.transport.import_data), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -1741,7 +1748,7 @@ def test_import_data_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.import_data), "__call__") as call: + with mock.patch.object(type(client.transport.import_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1786,9 +1793,7 @@ async def test_import_data_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.import_data), "__call__" - ) as call: + with mock.patch.object(type(client.transport.import_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1842,7 +1847,7 @@ def test_export_data(transport: str = "grpc", request_type=service.ExportDataReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_data), "__call__") as call: + with mock.patch.object(type(client.transport.export_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -1863,19 +1868,19 @@ def test_export_data_from_dict(): @pytest.mark.asyncio -async def test_export_data_async(transport: str = "grpc_asyncio"): +async def test_export_data_async( + transport: str = "grpc_asyncio", request_type=service.ExportDataRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ExportDataRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_data), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -1887,12 +1892,17 @@ async def test_export_data_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ExportDataRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_export_data_async_from_dict(): + await test_export_data_async(request_type=dict) + + def test_export_data_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1902,7 +1912,7 @@ def test_export_data_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_data), "__call__") as call: + with mock.patch.object(type(client.transport.export_data), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.export_data(request) @@ -1927,9 +1937,7 @@ async def test_export_data_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_data), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_data), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -1950,7 +1958,7 @@ def test_export_data_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_data), "__call__") as call: + with mock.patch.object(type(client.transport.export_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -2001,9 +2009,7 @@ async def test_export_data_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_data), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -2066,7 +2072,7 @@ def test_get_annotation_spec( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_annotation_spec), "__call__" + type(client.transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = annotation_spec.AnnotationSpec( @@ -2082,6 +2088,7 @@ def test_get_annotation_spec( assert args[0] == service.GetAnnotationSpecRequest() # Establish that the response is the type that we expect. + assert isinstance(response, annotation_spec.AnnotationSpec) assert response.name == "name_value" @@ -2096,18 +2103,20 @@ def test_get_annotation_spec_from_dict(): @pytest.mark.asyncio -async def test_get_annotation_spec_async(transport: str = "grpc_asyncio"): +async def test_get_annotation_spec_async( + transport: str = "grpc_asyncio", request_type=service.GetAnnotationSpecRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.GetAnnotationSpecRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_annotation_spec), "__call__" + type(client.transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -2124,7 +2133,7 @@ async def test_get_annotation_spec_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.GetAnnotationSpecRequest() # Establish that the response is the type that we expect. assert isinstance(response, annotation_spec.AnnotationSpec) @@ -2136,6 +2145,11 @@ async def test_get_annotation_spec_async(transport: str = "grpc_asyncio"): assert response.example_count == 1396 +@pytest.mark.asyncio +async def test_get_annotation_spec_async_from_dict(): + await test_get_annotation_spec_async(request_type=dict) + + def test_get_annotation_spec_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2146,7 +2160,7 @@ def test_get_annotation_spec_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_annotation_spec), "__call__" + type(client.transport.get_annotation_spec), "__call__" ) as call: call.return_value = annotation_spec.AnnotationSpec() @@ -2173,7 +2187,7 @@ async def test_get_annotation_spec_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_annotation_spec), "__call__" + type(client.transport.get_annotation_spec), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( annotation_spec.AnnotationSpec() @@ -2196,7 +2210,7 @@ def test_get_annotation_spec_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_annotation_spec), "__call__" + type(client.transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = annotation_spec.AnnotationSpec() @@ -2230,7 +2244,7 @@ async def test_get_annotation_spec_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_annotation_spec), "__call__" + type(client.transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = annotation_spec.AnnotationSpec() @@ -2272,7 +2286,7 @@ def test_create_model(transport: str = "grpc", request_type=service.CreateModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_model), "__call__") as call: + with mock.patch.object(type(client.transport.create_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -2293,19 +2307,19 @@ def test_create_model_from_dict(): @pytest.mark.asyncio -async def test_create_model_async(transport: str = "grpc_asyncio"): +async def test_create_model_async( + transport: str = "grpc_asyncio", request_type=service.CreateModelRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.CreateModelRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -2317,12 +2331,17 @@ async def test_create_model_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.CreateModelRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_create_model_async_from_dict(): + await test_create_model_async(request_type=dict) + + def test_create_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2332,7 +2351,7 @@ def test_create_model_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_model), "__call__") as call: + with mock.patch.object(type(client.transport.create_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.create_model(request) @@ -2357,9 +2376,7 @@ async def test_create_model_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_model), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -2380,7 +2397,7 @@ def test_create_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_model), "__call__") as call: + with mock.patch.object(type(client.transport.create_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -2431,9 +2448,7 @@ async def test_create_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -2493,7 +2508,7 @@ def test_get_model(transport: str = "grpc", request_type=service.GetModelRequest request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_model), "__call__") as call: + with mock.patch.object(type(client.transport.get_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = model.Model( name="name_value", @@ -2515,6 +2530,7 @@ def test_get_model(transport: str = "grpc", request_type=service.GetModelRequest assert args[0] == service.GetModelRequest() # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) assert response.name == "name_value" @@ -2533,19 +2549,19 @@ def test_get_model_from_dict(): @pytest.mark.asyncio -async def test_get_model_async(transport: str = "grpc_asyncio"): +async def test_get_model_async( + transport: str = "grpc_asyncio", request_type=service.GetModelRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.GetModelRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( model.Model( @@ -2563,7 +2579,7 @@ async def test_get_model_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.GetModelRequest() # Establish that the response is the type that we expect. assert isinstance(response, model.Model) @@ -2579,6 +2595,11 @@ async def test_get_model_async(transport: str = "grpc_asyncio"): assert response.etag == "etag_value" +@pytest.mark.asyncio +async def test_get_model_async_from_dict(): + await test_get_model_async(request_type=dict) + + def test_get_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2588,7 +2609,7 @@ def test_get_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_model), "__call__") as call: + with mock.patch.object(type(client.transport.get_model), "__call__") as call: call.return_value = model.Model() client.get_model(request) @@ -2613,9 +2634,7 @@ async def test_get_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_model), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) await client.get_model(request) @@ -2634,7 +2653,7 @@ def test_get_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_model), "__call__") as call: + with mock.patch.object(type(client.transport.get_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = model.Model() @@ -2666,9 +2685,7 @@ async def test_get_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = model.Model() @@ -2707,7 +2724,7 @@ def test_list_models(transport: str = "grpc", request_type=service.ListModelsReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_models), "__call__") as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelsResponse( next_page_token="next_page_token_value", @@ -2722,6 +2739,7 @@ def test_list_models(transport: str = "grpc", request_type=service.ListModelsReq assert args[0] == service.ListModelsRequest() # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsPager) assert response.next_page_token == "next_page_token_value" @@ -2732,19 +2750,19 @@ def test_list_models_from_dict(): @pytest.mark.asyncio -async def test_list_models_async(transport: str = "grpc_asyncio"): +async def test_list_models_async( + transport: str = "grpc_asyncio", request_type=service.ListModelsRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ListModelsRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_models), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListModelsResponse(next_page_token="next_page_token_value",) @@ -2756,7 +2774,7 @@ async def test_list_models_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ListModelsRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListModelsAsyncPager) @@ -2764,6 +2782,11 @@ async def test_list_models_async(transport: str = "grpc_asyncio"): assert response.next_page_token == "next_page_token_value" +@pytest.mark.asyncio +async def test_list_models_async_from_dict(): + await test_list_models_async(request_type=dict) + + def test_list_models_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2773,7 +2796,7 @@ def test_list_models_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_models), "__call__") as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: call.return_value = service.ListModelsResponse() client.list_models(request) @@ -2798,9 +2821,7 @@ async def test_list_models_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_models), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListModelsResponse() ) @@ -2821,7 +2842,7 @@ def test_list_models_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_models), "__call__") as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelsResponse() @@ -2853,9 +2874,7 @@ async def test_list_models_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_models), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelsResponse() @@ -2890,7 +2909,7 @@ def test_list_models_pager(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_models), "__call__") as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListModelsResponse( @@ -2920,7 +2939,7 @@ def test_list_models_pages(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_models), "__call__") as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListModelsResponse( @@ -2943,9 +2962,7 @@ async def test_list_models_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_models), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_models), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -2974,9 +2991,7 @@ async def test_list_models_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_models), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_models), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -3006,7 +3021,7 @@ def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_model), "__call__") as call: + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -3027,19 +3042,19 @@ def test_delete_model_from_dict(): @pytest.mark.asyncio -async def test_delete_model_async(transport: str = "grpc_asyncio"): +async def test_delete_model_async( + transport: str = "grpc_asyncio", request_type=service.DeleteModelRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.DeleteModelRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -3051,12 +3066,17 @@ async def test_delete_model_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.DeleteModelRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_delete_model_async_from_dict(): + await test_delete_model_async(request_type=dict) + + def test_delete_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3066,7 +3086,7 @@ def test_delete_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_model), "__call__") as call: + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.delete_model(request) @@ -3091,9 +3111,7 @@ async def test_delete_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -3114,7 +3132,7 @@ def test_delete_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_model), "__call__") as call: + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3146,9 +3164,7 @@ async def test_delete_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3189,7 +3205,7 @@ def test_update_model(transport: str = "grpc", request_type=service.UpdateModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_model), "__call__") as call: + with mock.patch.object(type(client.transport.update_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_model.Model( name="name_value", @@ -3211,6 +3227,7 @@ def test_update_model(transport: str = "grpc", request_type=service.UpdateModelR assert args[0] == service.UpdateModelRequest() # Establish that the response is the type that we expect. + assert isinstance(response, gca_model.Model) assert response.name == "name_value" @@ -3229,19 +3246,19 @@ def test_update_model_from_dict(): @pytest.mark.asyncio -async def test_update_model_async(transport: str = "grpc_asyncio"): +async def test_update_model_async( + transport: str = "grpc_asyncio", request_type=service.UpdateModelRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.UpdateModelRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( gca_model.Model( @@ -3259,7 +3276,7 @@ async def test_update_model_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.UpdateModelRequest() # Establish that the response is the type that we expect. assert isinstance(response, gca_model.Model) @@ -3275,6 +3292,11 @@ async def test_update_model_async(transport: str = "grpc_asyncio"): assert response.etag == "etag_value" +@pytest.mark.asyncio +async def test_update_model_async_from_dict(): + await test_update_model_async(request_type=dict) + + def test_update_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3284,7 +3306,7 @@ def test_update_model_field_headers(): request.model.name = "model.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_model), "__call__") as call: + with mock.patch.object(type(client.transport.update_model), "__call__") as call: call.return_value = gca_model.Model() client.update_model(request) @@ -3309,9 +3331,7 @@ async def test_update_model_field_headers_async(): request.model.name = "model.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_model), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gca_model.Model()) await client.update_model(request) @@ -3330,7 +3350,7 @@ def test_update_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_model), "__call__") as call: + with mock.patch.object(type(client.transport.update_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_model.Model() @@ -3381,9 +3401,7 @@ async def test_update_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_model.Model() @@ -3441,7 +3459,7 @@ def test_deploy_model(transport: str = "grpc", request_type=service.DeployModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.deploy_model), "__call__") as call: + with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -3462,19 +3480,19 @@ def test_deploy_model_from_dict(): @pytest.mark.asyncio -async def test_deploy_model_async(transport: str = "grpc_asyncio"): +async def test_deploy_model_async( + transport: str = "grpc_asyncio", request_type=service.DeployModelRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.DeployModelRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.deploy_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -3486,12 +3504,17 @@ async def test_deploy_model_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.DeployModelRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_deploy_model_async_from_dict(): + await test_deploy_model_async(request_type=dict) + + def test_deploy_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3501,7 +3524,7 @@ def test_deploy_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.deploy_model), "__call__") as call: + with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.deploy_model(request) @@ -3526,9 +3549,7 @@ async def test_deploy_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.deploy_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -3549,7 +3570,7 @@ def test_deploy_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.deploy_model), "__call__") as call: + with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3581,9 +3602,7 @@ async def test_deploy_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.deploy_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3626,7 +3645,7 @@ def test_undeploy_model( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.undeploy_model), "__call__") as call: + with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -3647,19 +3666,19 @@ def test_undeploy_model_from_dict(): @pytest.mark.asyncio -async def test_undeploy_model_async(transport: str = "grpc_asyncio"): +async def test_undeploy_model_async( + transport: str = "grpc_asyncio", request_type=service.UndeployModelRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.UndeployModelRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.undeploy_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -3671,12 +3690,17 @@ async def test_undeploy_model_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.UndeployModelRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_undeploy_model_async_from_dict(): + await test_undeploy_model_async(request_type=dict) + + def test_undeploy_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3686,7 +3710,7 @@ def test_undeploy_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.undeploy_model), "__call__") as call: + with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.undeploy_model(request) @@ -3711,9 +3735,7 @@ async def test_undeploy_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.undeploy_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -3734,7 +3756,7 @@ def test_undeploy_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.undeploy_model), "__call__") as call: + with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3766,9 +3788,7 @@ async def test_undeploy_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.undeploy_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3809,7 +3829,7 @@ def test_export_model(transport: str = "grpc", request_type=service.ExportModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_model), "__call__") as call: + with mock.patch.object(type(client.transport.export_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -3830,19 +3850,19 @@ def test_export_model_from_dict(): @pytest.mark.asyncio -async def test_export_model_async(transport: str = "grpc_asyncio"): +async def test_export_model_async( + transport: str = "grpc_asyncio", request_type=service.ExportModelRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ExportModelRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -3854,12 +3874,17 @@ async def test_export_model_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ExportModelRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_export_model_async_from_dict(): + await test_export_model_async(request_type=dict) + + def test_export_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3869,7 +3894,7 @@ def test_export_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_model), "__call__") as call: + with mock.patch.object(type(client.transport.export_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.export_model(request) @@ -3894,9 +3919,7 @@ async def test_export_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_model), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -3917,7 +3940,7 @@ def test_export_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_model), "__call__") as call: + with mock.patch.object(type(client.transport.export_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3968,9 +3991,7 @@ async def test_export_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -4033,7 +4054,7 @@ def test_get_model_evaluation( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_model_evaluation), "__call__" + type(client.transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = model_evaluation.ModelEvaluation( @@ -4055,6 +4076,7 @@ def test_get_model_evaluation( assert args[0] == service.GetModelEvaluationRequest() # Establish that the response is the type that we expect. + assert isinstance(response, model_evaluation.ModelEvaluation) assert response.name == "name_value" @@ -4071,18 +4093,20 @@ def test_get_model_evaluation_from_dict(): @pytest.mark.asyncio -async def test_get_model_evaluation_async(transport: str = "grpc_asyncio"): +async def test_get_model_evaluation_async( + transport: str = "grpc_asyncio", request_type=service.GetModelEvaluationRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.GetModelEvaluationRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_model_evaluation), "__call__" + type(client.transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -4100,7 +4124,7 @@ async def test_get_model_evaluation_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.GetModelEvaluationRequest() # Establish that the response is the type that we expect. assert isinstance(response, model_evaluation.ModelEvaluation) @@ -4114,6 +4138,11 @@ async def test_get_model_evaluation_async(transport: str = "grpc_asyncio"): assert response.evaluated_example_count == 2446 +@pytest.mark.asyncio +async def test_get_model_evaluation_async_from_dict(): + await test_get_model_evaluation_async(request_type=dict) + + def test_get_model_evaluation_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4124,7 +4153,7 @@ def test_get_model_evaluation_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_model_evaluation), "__call__" + type(client.transport.get_model_evaluation), "__call__" ) as call: call.return_value = model_evaluation.ModelEvaluation() @@ -4151,7 +4180,7 @@ async def test_get_model_evaluation_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_model_evaluation), "__call__" + type(client.transport.get_model_evaluation), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( model_evaluation.ModelEvaluation() @@ -4174,7 +4203,7 @@ def test_get_model_evaluation_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_model_evaluation), "__call__" + type(client.transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = model_evaluation.ModelEvaluation() @@ -4208,7 +4237,7 @@ async def test_get_model_evaluation_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_model_evaluation), "__call__" + type(client.transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = model_evaluation.ModelEvaluation() @@ -4253,7 +4282,7 @@ def test_list_model_evaluations( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelEvaluationsResponse( @@ -4269,6 +4298,7 @@ def test_list_model_evaluations( assert args[0] == service.ListModelEvaluationsRequest() # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelEvaluationsPager) assert response.next_page_token == "next_page_token_value" @@ -4279,18 +4309,20 @@ def test_list_model_evaluations_from_dict(): @pytest.mark.asyncio -async def test_list_model_evaluations_async(transport: str = "grpc_asyncio"): +async def test_list_model_evaluations_async( + transport: str = "grpc_asyncio", request_type=service.ListModelEvaluationsRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ListModelEvaluationsRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -4305,7 +4337,7 @@ async def test_list_model_evaluations_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ListModelEvaluationsRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListModelEvaluationsAsyncPager) @@ -4313,6 +4345,11 @@ async def test_list_model_evaluations_async(transport: str = "grpc_asyncio"): assert response.next_page_token == "next_page_token_value" +@pytest.mark.asyncio +async def test_list_model_evaluations_async_from_dict(): + await test_list_model_evaluations_async(request_type=dict) + + def test_list_model_evaluations_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4323,7 +4360,7 @@ def test_list_model_evaluations_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: call.return_value = service.ListModelEvaluationsResponse() @@ -4350,7 +4387,7 @@ async def test_list_model_evaluations_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListModelEvaluationsResponse() @@ -4373,7 +4410,7 @@ def test_list_model_evaluations_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelEvaluationsResponse() @@ -4413,7 +4450,7 @@ async def test_list_model_evaluations_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelEvaluationsResponse() @@ -4456,7 +4493,7 @@ def test_list_model_evaluations_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -4502,7 +4539,7 @@ def test_list_model_evaluations_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -4540,7 +4577,7 @@ async def test_list_model_evaluations_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_model_evaluations), + type(client.transport.list_model_evaluations), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -4585,7 +4622,7 @@ async def test_list_model_evaluations_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_model_evaluations), + type(client.transport.list_model_evaluations), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -4657,7 +4694,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = AutoMlClient(transport=transport) - assert client._transport is transport + assert client.transport is transport def test_transport_get_channel(): @@ -4690,7 +4727,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client._transport, transports.AutoMlGrpcTransport,) + assert isinstance(client.transport, transports.AutoMlGrpcTransport,) def test_auto_ml_base_transport_error(): @@ -4806,7 +4843,7 @@ def test_auto_ml_host_no_port(): api_endpoint="automl.googleapis.com" ), ) - assert client._transport._host == "automl.googleapis.com:443" + assert client.transport._host == "automl.googleapis.com:443" def test_auto_ml_host_with_port(): @@ -4816,7 +4853,7 @@ def test_auto_ml_host_with_port(): api_endpoint="automl.googleapis.com:8000" ), ) - assert client._transport._host == "automl.googleapis.com:8000" + assert client.transport._host == "automl.googleapis.com:8000" def test_auto_ml_grpc_transport_channel(): @@ -4924,7 +4961,7 @@ def test_auto_ml_grpc_lro_client(): client = AutoMlClient( credentials=credentials.AnonymousCredentials(), transport="grpc", ) - transport = client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsClient,) @@ -4937,7 +4974,7 @@ def test_auto_ml_grpc_lro_async_client(): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", ) - transport = client._client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,) @@ -4946,10 +4983,42 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_dataset_path(): +def test_annotation_spec_path(): project = "squid" location = "clam" dataset = "whelk" + annotation_spec = "octopus" + + expected = "projects/{project}/locations/{location}/datasets/{dataset}/annotationSpecs/{annotation_spec}".format( + project=project, + location=location, + dataset=dataset, + annotation_spec=annotation_spec, + ) + actual = AutoMlClient.annotation_spec_path( + project, location, dataset, annotation_spec + ) + assert expected == actual + + +def test_parse_annotation_spec_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "dataset": "cuttlefish", + "annotation_spec": "mussel", + } + path = AutoMlClient.annotation_spec_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_annotation_spec_path(path) + assert expected == actual + + +def test_dataset_path(): + project = "winkle" + location = "nautilus" + dataset = "scallop" expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( project=project, location=location, dataset=dataset, @@ -4960,9 +5029,9 @@ def test_dataset_path(): def test_parse_dataset_path(): expected = { - "project": "octopus", - "location": "oyster", - "dataset": "nudibranch", + "project": "abalone", + "location": "squid", + "dataset": "clam", } path = AutoMlClient.dataset_path(**expected) @@ -4972,9 +5041,9 @@ def test_parse_dataset_path(): def test_model_path(): - project = "squid" - location = "clam" - model = "whelk" + project = "whelk" + location = "octopus" + model = "oyster" expected = "projects/{project}/locations/{location}/models/{model}".format( project=project, location=location, model=model, @@ -4985,9 +5054,9 @@ def test_model_path(): def test_parse_model_path(): expected = { - "project": "octopus", - "location": "oyster", - "model": "nudibranch", + "project": "nudibranch", + "location": "cuttlefish", + "model": "mussel", } path = AutoMlClient.model_path(**expected) @@ -4996,6 +5065,139 @@ def test_parse_model_path(): assert expected == actual +def test_model_evaluation_path(): + project = "winkle" + location = "nautilus" + model = "scallop" + model_evaluation = "abalone" + + expected = "projects/{project}/locations/{location}/models/{model}/modelEvaluations/{model_evaluation}".format( + project=project, + location=location, + model=model, + model_evaluation=model_evaluation, + ) + actual = AutoMlClient.model_evaluation_path( + project, location, model, model_evaluation + ) + assert expected == actual + + +def test_parse_model_evaluation_path(): + expected = { + "project": "squid", + "location": "clam", + "model": "whelk", + "model_evaluation": "octopus", + } + path = AutoMlClient.model_evaluation_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_model_evaluation_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "oyster" + + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = AutoMlClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nudibranch", + } + path = AutoMlClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "cuttlefish" + + expected = "folders/{folder}".format(folder=folder,) + actual = AutoMlClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "mussel", + } + path = AutoMlClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "winkle" + + expected = "organizations/{organization}".format(organization=organization,) + actual = AutoMlClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nautilus", + } + path = AutoMlClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "scallop" + + expected = "projects/{project}".format(project=project,) + actual = AutoMlClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "abalone", + } + path = AutoMlClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "squid" + location = "clam" + + expected = "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + actual = AutoMlClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "whelk", + "location": "octopus", + } + path = AutoMlClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_common_location_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() diff --git a/tests/unit/gapic/automl_v1/test_prediction_service.py b/tests/unit/gapic/automl_v1/test_prediction_service.py index fd886203..6fba03de 100644 --- a/tests/unit/gapic/automl_v1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1/test_prediction_service.py @@ -106,12 +106,12 @@ def test_prediction_service_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds - assert client._transport._host == "automl.googleapis.com:443" + assert client.transport._host == "automl.googleapis.com:443" def test_prediction_service_client_get_transport_class(): @@ -471,7 +471,7 @@ def test_predict( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.predict), "__call__") as call: + with mock.patch.object(type(client.transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = prediction_service.PredictResponse() @@ -484,6 +484,7 @@ def test_predict( assert args[0] == prediction_service.PredictRequest() # Establish that the response is the type that we expect. + assert isinstance(response, prediction_service.PredictResponse) @@ -492,17 +493,19 @@ def test_predict_from_dict(): @pytest.mark.asyncio -async def test_predict_async(transport: str = "grpc_asyncio"): +async def test_predict_async( + transport: str = "grpc_asyncio", request_type=prediction_service.PredictRequest +): client = PredictionServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = prediction_service.PredictRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._client._transport.predict), "__call__") as call: + with mock.patch.object(type(client.transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( prediction_service.PredictResponse() @@ -514,12 +517,17 @@ async def test_predict_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == prediction_service.PredictRequest() # Establish that the response is the type that we expect. assert isinstance(response, prediction_service.PredictResponse) +@pytest.mark.asyncio +async def test_predict_async_from_dict(): + await test_predict_async(request_type=dict) + + def test_predict_field_headers(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -529,7 +537,7 @@ def test_predict_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.predict), "__call__") as call: + with mock.patch.object(type(client.transport.predict), "__call__") as call: call.return_value = prediction_service.PredictResponse() client.predict(request) @@ -556,7 +564,7 @@ async def test_predict_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._client._transport.predict), "__call__") as call: + with mock.patch.object(type(client.transport.predict), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( prediction_service.PredictResponse() ) @@ -577,7 +585,7 @@ def test_predict_flattened(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.predict), "__call__") as call: + with mock.patch.object(type(client.transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = prediction_service.PredictResponse() @@ -628,7 +636,7 @@ async def test_predict_flattened_async(): ) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._client._transport.predict), "__call__") as call: + with mock.patch.object(type(client.transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = prediction_service.PredictResponse() @@ -690,7 +698,7 @@ def test_batch_predict( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.batch_predict), "__call__") as call: + with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -711,19 +719,19 @@ def test_batch_predict_from_dict(): @pytest.mark.asyncio -async def test_batch_predict_async(transport: str = "grpc_asyncio"): +async def test_batch_predict_async( + transport: str = "grpc_asyncio", request_type=prediction_service.BatchPredictRequest +): client = PredictionServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = prediction_service.BatchPredictRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.batch_predict), "__call__" - ) as call: + with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -735,12 +743,17 @@ async def test_batch_predict_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == prediction_service.BatchPredictRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_batch_predict_async_from_dict(): + await test_batch_predict_async(request_type=dict) + + def test_batch_predict_field_headers(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -750,7 +763,7 @@ def test_batch_predict_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.batch_predict), "__call__") as call: + with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.batch_predict(request) @@ -777,9 +790,7 @@ async def test_batch_predict_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.batch_predict), "__call__" - ) as call: + with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -800,7 +811,7 @@ def test_batch_predict_flattened(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.batch_predict), "__call__") as call: + with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -867,9 +878,7 @@ async def test_batch_predict_flattened_async(): ) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.batch_predict), "__call__" - ) as call: + with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -971,7 +980,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = PredictionServiceClient(transport=transport) - assert client._transport is transport + assert client.transport is transport def test_transport_get_channel(): @@ -1007,7 +1016,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client._transport, transports.PredictionServiceGrpcTransport,) + assert isinstance(client.transport, transports.PredictionServiceGrpcTransport,) def test_prediction_service_base_transport_error(): @@ -1107,7 +1116,7 @@ def test_prediction_service_host_no_port(): api_endpoint="automl.googleapis.com" ), ) - assert client._transport._host == "automl.googleapis.com:443" + assert client.transport._host == "automl.googleapis.com:443" def test_prediction_service_host_with_port(): @@ -1117,7 +1126,7 @@ def test_prediction_service_host_with_port(): api_endpoint="automl.googleapis.com:8000" ), ) - assert client._transport._host == "automl.googleapis.com:8000" + assert client.transport._host == "automl.googleapis.com:8000" def test_prediction_service_grpc_transport_channel(): @@ -1233,7 +1242,7 @@ def test_prediction_service_grpc_lro_client(): client = PredictionServiceClient( credentials=credentials.AnonymousCredentials(), transport="grpc", ) - transport = client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsClient,) @@ -1246,7 +1255,7 @@ def test_prediction_service_grpc_lro_async_client(): client = PredictionServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", ) - transport = client._client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,) @@ -1255,6 +1264,132 @@ def test_prediction_service_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client +def test_model_path(): + project = "squid" + location = "clam" + model = "whelk" + + expected = "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, + ) + actual = PredictionServiceClient.model_path(project, location, model) + assert expected == actual + + +def test_parse_model_path(): + expected = { + "project": "octopus", + "location": "oyster", + "model": "nudibranch", + } + path = PredictionServiceClient.model_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_model_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = PredictionServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = PredictionServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + + expected = "folders/{folder}".format(folder=folder,) + actual = PredictionServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = PredictionServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + + expected = "organizations/{organization}".format(organization=organization,) + actual = PredictionServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = PredictionServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + + expected = "projects/{project}".format(project=project,) + actual = PredictionServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = PredictionServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + + expected = "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + actual = PredictionServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = PredictionServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_location_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() diff --git a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py index 09cb0749..1cfdb65b 100644 --- a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py @@ -44,7 +44,6 @@ from google.cloud.automl_v1beta1.types import column_spec from google.cloud.automl_v1beta1.types import column_spec as gca_column_spec from google.cloud.automl_v1beta1.types import data_stats -from google.cloud.automl_v1beta1.types import data_stats as gca_data_stats from google.cloud.automl_v1beta1.types import data_types from google.cloud.automl_v1beta1.types import dataset from google.cloud.automl_v1beta1.types import dataset as gca_dataset @@ -117,12 +116,12 @@ def test_auto_ml_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds - assert client._transport._host == "automl.googleapis.com:443" + assert client.transport._host == "automl.googleapis.com:443" def test_auto_ml_client_get_transport_class(): @@ -448,7 +447,7 @@ def test_create_dataset( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset( name="name_value", @@ -470,6 +469,7 @@ def test_create_dataset( assert args[0] == service.CreateDatasetRequest() # Establish that the response is the type that we expect. + assert isinstance(response, gca_dataset.Dataset) assert response.name == "name_value" @@ -488,19 +488,19 @@ def test_create_dataset_from_dict(): @pytest.mark.asyncio -async def test_create_dataset_async(transport: str = "grpc_asyncio"): +async def test_create_dataset_async( + transport: str = "grpc_asyncio", request_type=service.CreateDatasetRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.CreateDatasetRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( gca_dataset.Dataset( @@ -518,7 +518,7 @@ async def test_create_dataset_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.CreateDatasetRequest() # Establish that the response is the type that we expect. assert isinstance(response, gca_dataset.Dataset) @@ -534,6 +534,11 @@ async def test_create_dataset_async(transport: str = "grpc_asyncio"): assert response.etag == "etag_value" +@pytest.mark.asyncio +async def test_create_dataset_async_from_dict(): + await test_create_dataset_async(request_type=dict) + + def test_create_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -543,7 +548,7 @@ def test_create_dataset_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: call.return_value = gca_dataset.Dataset() client.create_dataset(request) @@ -568,9 +573,7 @@ async def test_create_dataset_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gca_dataset.Dataset()) await client.create_dataset(request) @@ -589,7 +592,7 @@ def test_create_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset() @@ -640,9 +643,7 @@ async def test_create_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset() @@ -700,7 +701,7 @@ def test_get_dataset(transport: str = "grpc", request_type=service.GetDatasetReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = dataset.Dataset( name="name_value", @@ -722,6 +723,7 @@ def test_get_dataset(transport: str = "grpc", request_type=service.GetDatasetReq assert args[0] == service.GetDatasetRequest() # Establish that the response is the type that we expect. + assert isinstance(response, dataset.Dataset) assert response.name == "name_value" @@ -740,19 +742,19 @@ def test_get_dataset_from_dict(): @pytest.mark.asyncio -async def test_get_dataset_async(transport: str = "grpc_asyncio"): +async def test_get_dataset_async( + transport: str = "grpc_asyncio", request_type=service.GetDatasetRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.GetDatasetRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( dataset.Dataset( @@ -770,7 +772,7 @@ async def test_get_dataset_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.GetDatasetRequest() # Establish that the response is the type that we expect. assert isinstance(response, dataset.Dataset) @@ -786,6 +788,11 @@ async def test_get_dataset_async(transport: str = "grpc_asyncio"): assert response.etag == "etag_value" +@pytest.mark.asyncio +async def test_get_dataset_async_from_dict(): + await test_get_dataset_async(request_type=dict) + + def test_get_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -795,7 +802,7 @@ def test_get_dataset_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: call.return_value = dataset.Dataset() client.get_dataset(request) @@ -820,9 +827,7 @@ async def test_get_dataset_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(dataset.Dataset()) await client.get_dataset(request) @@ -841,7 +846,7 @@ def test_get_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = dataset.Dataset() @@ -873,9 +878,7 @@ async def test_get_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = dataset.Dataset() @@ -916,7 +919,7 @@ def test_list_datasets( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListDatasetsResponse( next_page_token="next_page_token_value", @@ -931,6 +934,7 @@ def test_list_datasets( assert args[0] == service.ListDatasetsRequest() # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDatasetsPager) assert response.next_page_token == "next_page_token_value" @@ -941,19 +945,19 @@ def test_list_datasets_from_dict(): @pytest.mark.asyncio -async def test_list_datasets_async(transport: str = "grpc_asyncio"): +async def test_list_datasets_async( + transport: str = "grpc_asyncio", request_type=service.ListDatasetsRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ListDatasetsRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_datasets), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListDatasetsResponse(next_page_token="next_page_token_value",) @@ -965,7 +969,7 @@ async def test_list_datasets_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ListDatasetsRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListDatasetsAsyncPager) @@ -973,6 +977,11 @@ async def test_list_datasets_async(transport: str = "grpc_asyncio"): assert response.next_page_token == "next_page_token_value" +@pytest.mark.asyncio +async def test_list_datasets_async_from_dict(): + await test_list_datasets_async(request_type=dict) + + def test_list_datasets_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -982,7 +991,7 @@ def test_list_datasets_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: call.return_value = service.ListDatasetsResponse() client.list_datasets(request) @@ -1007,9 +1016,7 @@ async def test_list_datasets_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_datasets), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListDatasetsResponse() ) @@ -1030,7 +1037,7 @@ def test_list_datasets_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListDatasetsResponse() @@ -1062,9 +1069,7 @@ async def test_list_datasets_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_datasets), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListDatasetsResponse() @@ -1099,7 +1104,7 @@ def test_list_datasets_pager(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListDatasetsResponse( @@ -1133,7 +1138,7 @@ def test_list_datasets_pages(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListDatasetsResponse( @@ -1160,9 +1165,7 @@ async def test_list_datasets_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_datasets), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_datasets), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -1195,9 +1198,7 @@ async def test_list_datasets_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_datasets), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_datasets), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -1233,7 +1234,7 @@ def test_update_dataset( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset( name="name_value", @@ -1255,6 +1256,7 @@ def test_update_dataset( assert args[0] == service.UpdateDatasetRequest() # Establish that the response is the type that we expect. + assert isinstance(response, gca_dataset.Dataset) assert response.name == "name_value" @@ -1273,19 +1275,19 @@ def test_update_dataset_from_dict(): @pytest.mark.asyncio -async def test_update_dataset_async(transport: str = "grpc_asyncio"): +async def test_update_dataset_async( + transport: str = "grpc_asyncio", request_type=service.UpdateDatasetRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.UpdateDatasetRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( gca_dataset.Dataset( @@ -1303,7 +1305,7 @@ async def test_update_dataset_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.UpdateDatasetRequest() # Establish that the response is the type that we expect. assert isinstance(response, gca_dataset.Dataset) @@ -1319,6 +1321,11 @@ async def test_update_dataset_async(transport: str = "grpc_asyncio"): assert response.etag == "etag_value" +@pytest.mark.asyncio +async def test_update_dataset_async_from_dict(): + await test_update_dataset_async(request_type=dict) + + def test_update_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1328,7 +1335,7 @@ def test_update_dataset_field_headers(): request.dataset.name = "dataset.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: call.return_value = gca_dataset.Dataset() client.update_dataset(request) @@ -1355,9 +1362,7 @@ async def test_update_dataset_field_headers_async(): request.dataset.name = "dataset.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gca_dataset.Dataset()) await client.update_dataset(request) @@ -1378,7 +1383,7 @@ def test_update_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset() @@ -1425,9 +1430,7 @@ async def test_update_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset() @@ -1483,7 +1486,7 @@ def test_delete_dataset( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -1504,19 +1507,19 @@ def test_delete_dataset_from_dict(): @pytest.mark.asyncio -async def test_delete_dataset_async(transport: str = "grpc_asyncio"): +async def test_delete_dataset_async( + transport: str = "grpc_asyncio", request_type=service.DeleteDatasetRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.DeleteDatasetRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -1528,12 +1531,17 @@ async def test_delete_dataset_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.DeleteDatasetRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_delete_dataset_async_from_dict(): + await test_delete_dataset_async(request_type=dict) + + def test_delete_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1543,7 +1551,7 @@ def test_delete_dataset_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.delete_dataset(request) @@ -1568,9 +1576,7 @@ async def test_delete_dataset_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -1591,7 +1597,7 @@ def test_delete_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_dataset), "__call__") as call: + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1623,9 +1629,7 @@ async def test_delete_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_dataset), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1666,7 +1670,7 @@ def test_import_data(transport: str = "grpc", request_type=service.ImportDataReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.import_data), "__call__") as call: + with mock.patch.object(type(client.transport.import_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -1687,19 +1691,19 @@ def test_import_data_from_dict(): @pytest.mark.asyncio -async def test_import_data_async(transport: str = "grpc_asyncio"): +async def test_import_data_async( + transport: str = "grpc_asyncio", request_type=service.ImportDataRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ImportDataRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.import_data), "__call__" - ) as call: + with mock.patch.object(type(client.transport.import_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -1711,12 +1715,17 @@ async def test_import_data_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ImportDataRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_import_data_async_from_dict(): + await test_import_data_async(request_type=dict) + + def test_import_data_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1726,7 +1735,7 @@ def test_import_data_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.import_data), "__call__") as call: + with mock.patch.object(type(client.transport.import_data), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.import_data(request) @@ -1751,9 +1760,7 @@ async def test_import_data_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.import_data), "__call__" - ) as call: + with mock.patch.object(type(client.transport.import_data), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -1774,7 +1781,7 @@ def test_import_data_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.import_data), "__call__") as call: + with mock.patch.object(type(client.transport.import_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1819,9 +1826,7 @@ async def test_import_data_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.import_data), "__call__" - ) as call: + with mock.patch.object(type(client.transport.import_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1875,7 +1880,7 @@ def test_export_data(transport: str = "grpc", request_type=service.ExportDataReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_data), "__call__") as call: + with mock.patch.object(type(client.transport.export_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -1896,19 +1901,19 @@ def test_export_data_from_dict(): @pytest.mark.asyncio -async def test_export_data_async(transport: str = "grpc_asyncio"): +async def test_export_data_async( + transport: str = "grpc_asyncio", request_type=service.ExportDataRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ExportDataRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_data), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -1920,12 +1925,17 @@ async def test_export_data_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ExportDataRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_export_data_async_from_dict(): + await test_export_data_async(request_type=dict) + + def test_export_data_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1935,7 +1945,7 @@ def test_export_data_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_data), "__call__") as call: + with mock.patch.object(type(client.transport.export_data), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.export_data(request) @@ -1960,9 +1970,7 @@ async def test_export_data_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_data), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_data), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -1983,7 +1991,7 @@ def test_export_data_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_data), "__call__") as call: + with mock.patch.object(type(client.transport.export_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -2034,9 +2042,7 @@ async def test_export_data_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_data), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -2099,7 +2105,7 @@ def test_get_annotation_spec( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_annotation_spec), "__call__" + type(client.transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = annotation_spec.AnnotationSpec( @@ -2115,6 +2121,7 @@ def test_get_annotation_spec( assert args[0] == service.GetAnnotationSpecRequest() # Establish that the response is the type that we expect. + assert isinstance(response, annotation_spec.AnnotationSpec) assert response.name == "name_value" @@ -2129,18 +2136,20 @@ def test_get_annotation_spec_from_dict(): @pytest.mark.asyncio -async def test_get_annotation_spec_async(transport: str = "grpc_asyncio"): +async def test_get_annotation_spec_async( + transport: str = "grpc_asyncio", request_type=service.GetAnnotationSpecRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.GetAnnotationSpecRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_annotation_spec), "__call__" + type(client.transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -2157,7 +2166,7 @@ async def test_get_annotation_spec_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.GetAnnotationSpecRequest() # Establish that the response is the type that we expect. assert isinstance(response, annotation_spec.AnnotationSpec) @@ -2169,6 +2178,11 @@ async def test_get_annotation_spec_async(transport: str = "grpc_asyncio"): assert response.example_count == 1396 +@pytest.mark.asyncio +async def test_get_annotation_spec_async_from_dict(): + await test_get_annotation_spec_async(request_type=dict) + + def test_get_annotation_spec_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2179,7 +2193,7 @@ def test_get_annotation_spec_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_annotation_spec), "__call__" + type(client.transport.get_annotation_spec), "__call__" ) as call: call.return_value = annotation_spec.AnnotationSpec() @@ -2206,7 +2220,7 @@ async def test_get_annotation_spec_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_annotation_spec), "__call__" + type(client.transport.get_annotation_spec), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( annotation_spec.AnnotationSpec() @@ -2229,7 +2243,7 @@ def test_get_annotation_spec_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_annotation_spec), "__call__" + type(client.transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = annotation_spec.AnnotationSpec() @@ -2263,7 +2277,7 @@ async def test_get_annotation_spec_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_annotation_spec), "__call__" + type(client.transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = annotation_spec.AnnotationSpec() @@ -2307,7 +2321,7 @@ def test_get_table_spec( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_table_spec), "__call__") as call: + with mock.patch.object(type(client.transport.get_table_spec), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = table_spec.TableSpec( name="name_value", @@ -2327,6 +2341,7 @@ def test_get_table_spec( assert args[0] == service.GetTableSpecRequest() # Establish that the response is the type that we expect. + assert isinstance(response, table_spec.TableSpec) assert response.name == "name_value" @@ -2347,19 +2362,19 @@ def test_get_table_spec_from_dict(): @pytest.mark.asyncio -async def test_get_table_spec_async(transport: str = "grpc_asyncio"): +async def test_get_table_spec_async( + transport: str = "grpc_asyncio", request_type=service.GetTableSpecRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.GetTableSpecRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_table_spec), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_table_spec), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( table_spec.TableSpec( @@ -2378,7 +2393,7 @@ async def test_get_table_spec_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.GetTableSpecRequest() # Establish that the response is the type that we expect. assert isinstance(response, table_spec.TableSpec) @@ -2396,6 +2411,11 @@ async def test_get_table_spec_async(transport: str = "grpc_asyncio"): assert response.etag == "etag_value" +@pytest.mark.asyncio +async def test_get_table_spec_async_from_dict(): + await test_get_table_spec_async(request_type=dict) + + def test_get_table_spec_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2405,7 +2425,7 @@ def test_get_table_spec_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_table_spec), "__call__") as call: + with mock.patch.object(type(client.transport.get_table_spec), "__call__") as call: call.return_value = table_spec.TableSpec() client.get_table_spec(request) @@ -2430,9 +2450,7 @@ async def test_get_table_spec_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_table_spec), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_table_spec), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( table_spec.TableSpec() ) @@ -2453,7 +2471,7 @@ def test_get_table_spec_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_table_spec), "__call__") as call: + with mock.patch.object(type(client.transport.get_table_spec), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = table_spec.TableSpec() @@ -2485,9 +2503,7 @@ async def test_get_table_spec_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_table_spec), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_table_spec), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = table_spec.TableSpec() @@ -2530,9 +2546,7 @@ def test_list_table_specs( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_table_specs), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListTableSpecsResponse( next_page_token="next_page_token_value", @@ -2547,6 +2561,7 @@ def test_list_table_specs( assert args[0] == service.ListTableSpecsRequest() # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListTableSpecsPager) assert response.next_page_token == "next_page_token_value" @@ -2557,19 +2572,19 @@ def test_list_table_specs_from_dict(): @pytest.mark.asyncio -async def test_list_table_specs_async(transport: str = "grpc_asyncio"): +async def test_list_table_specs_async( + transport: str = "grpc_asyncio", request_type=service.ListTableSpecsRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ListTableSpecsRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_table_specs), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListTableSpecsResponse(next_page_token="next_page_token_value",) @@ -2581,7 +2596,7 @@ async def test_list_table_specs_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ListTableSpecsRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListTableSpecsAsyncPager) @@ -2589,6 +2604,11 @@ async def test_list_table_specs_async(transport: str = "grpc_asyncio"): assert response.next_page_token == "next_page_token_value" +@pytest.mark.asyncio +async def test_list_table_specs_async_from_dict(): + await test_list_table_specs_async(request_type=dict) + + def test_list_table_specs_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2598,9 +2618,7 @@ def test_list_table_specs_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_table_specs), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: call.return_value = service.ListTableSpecsResponse() client.list_table_specs(request) @@ -2625,9 +2643,7 @@ async def test_list_table_specs_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_table_specs), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListTableSpecsResponse() ) @@ -2648,9 +2664,7 @@ def test_list_table_specs_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_table_specs), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListTableSpecsResponse() @@ -2682,9 +2696,7 @@ async def test_list_table_specs_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_table_specs), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListTableSpecsResponse() @@ -2719,9 +2731,7 @@ def test_list_table_specs_pager(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_table_specs), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListTableSpecsResponse( @@ -2759,9 +2769,7 @@ def test_list_table_specs_pages(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_table_specs), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListTableSpecsResponse( @@ -2792,9 +2800,7 @@ async def test_list_table_specs_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_table_specs), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_table_specs), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -2831,9 +2837,7 @@ async def test_list_table_specs_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_table_specs), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_table_specs), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -2874,7 +2878,7 @@ def test_update_table_spec( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.update_table_spec), "__call__" + type(client.transport.update_table_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = gca_table_spec.TableSpec( @@ -2895,6 +2899,7 @@ def test_update_table_spec( assert args[0] == service.UpdateTableSpecRequest() # Establish that the response is the type that we expect. + assert isinstance(response, gca_table_spec.TableSpec) assert response.name == "name_value" @@ -2915,18 +2920,20 @@ def test_update_table_spec_from_dict(): @pytest.mark.asyncio -async def test_update_table_spec_async(transport: str = "grpc_asyncio"): +async def test_update_table_spec_async( + transport: str = "grpc_asyncio", request_type=service.UpdateTableSpecRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.UpdateTableSpecRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.update_table_spec), "__call__" + type(client.transport.update_table_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -2946,7 +2953,7 @@ async def test_update_table_spec_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.UpdateTableSpecRequest() # Establish that the response is the type that we expect. assert isinstance(response, gca_table_spec.TableSpec) @@ -2964,6 +2971,11 @@ async def test_update_table_spec_async(transport: str = "grpc_asyncio"): assert response.etag == "etag_value" +@pytest.mark.asyncio +async def test_update_table_spec_async_from_dict(): + await test_update_table_spec_async(request_type=dict) + + def test_update_table_spec_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2974,7 +2986,7 @@ def test_update_table_spec_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.update_table_spec), "__call__" + type(client.transport.update_table_spec), "__call__" ) as call: call.return_value = gca_table_spec.TableSpec() @@ -3003,7 +3015,7 @@ async def test_update_table_spec_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.update_table_spec), "__call__" + type(client.transport.update_table_spec), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( gca_table_spec.TableSpec() @@ -3028,7 +3040,7 @@ def test_update_table_spec_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.update_table_spec), "__call__" + type(client.transport.update_table_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = gca_table_spec.TableSpec() @@ -3065,7 +3077,7 @@ async def test_update_table_spec_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.update_table_spec), "__call__" + type(client.transport.update_table_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = gca_table_spec.TableSpec() @@ -3112,7 +3124,7 @@ def test_get_column_spec( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_column_spec), "__call__") as call: + with mock.patch.object(type(client.transport.get_column_spec), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = column_spec.ColumnSpec( name="name_value", display_name="display_name_value", etag="etag_value", @@ -3127,6 +3139,7 @@ def test_get_column_spec( assert args[0] == service.GetColumnSpecRequest() # Establish that the response is the type that we expect. + assert isinstance(response, column_spec.ColumnSpec) assert response.name == "name_value" @@ -3141,19 +3154,19 @@ def test_get_column_spec_from_dict(): @pytest.mark.asyncio -async def test_get_column_spec_async(transport: str = "grpc_asyncio"): +async def test_get_column_spec_async( + transport: str = "grpc_asyncio", request_type=service.GetColumnSpecRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.GetColumnSpecRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_column_spec), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_column_spec), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( column_spec.ColumnSpec( @@ -3167,7 +3180,7 @@ async def test_get_column_spec_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.GetColumnSpecRequest() # Establish that the response is the type that we expect. assert isinstance(response, column_spec.ColumnSpec) @@ -3179,6 +3192,11 @@ async def test_get_column_spec_async(transport: str = "grpc_asyncio"): assert response.etag == "etag_value" +@pytest.mark.asyncio +async def test_get_column_spec_async_from_dict(): + await test_get_column_spec_async(request_type=dict) + + def test_get_column_spec_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3188,7 +3206,7 @@ def test_get_column_spec_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_column_spec), "__call__") as call: + with mock.patch.object(type(client.transport.get_column_spec), "__call__") as call: call.return_value = column_spec.ColumnSpec() client.get_column_spec(request) @@ -3213,9 +3231,7 @@ async def test_get_column_spec_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_column_spec), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_column_spec), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( column_spec.ColumnSpec() ) @@ -3236,7 +3252,7 @@ def test_get_column_spec_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_column_spec), "__call__") as call: + with mock.patch.object(type(client.transport.get_column_spec), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = column_spec.ColumnSpec() @@ -3268,9 +3284,7 @@ async def test_get_column_spec_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_column_spec), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_column_spec), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = column_spec.ColumnSpec() @@ -3314,7 +3328,7 @@ def test_list_column_specs( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_column_specs), "__call__" + type(client.transport.list_column_specs), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListColumnSpecsResponse( @@ -3330,6 +3344,7 @@ def test_list_column_specs( assert args[0] == service.ListColumnSpecsRequest() # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListColumnSpecsPager) assert response.next_page_token == "next_page_token_value" @@ -3340,18 +3355,20 @@ def test_list_column_specs_from_dict(): @pytest.mark.asyncio -async def test_list_column_specs_async(transport: str = "grpc_asyncio"): +async def test_list_column_specs_async( + transport: str = "grpc_asyncio", request_type=service.ListColumnSpecsRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ListColumnSpecsRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_column_specs), "__call__" + type(client.transport.list_column_specs), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -3364,7 +3381,7 @@ async def test_list_column_specs_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ListColumnSpecsRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListColumnSpecsAsyncPager) @@ -3372,6 +3389,11 @@ async def test_list_column_specs_async(transport: str = "grpc_asyncio"): assert response.next_page_token == "next_page_token_value" +@pytest.mark.asyncio +async def test_list_column_specs_async_from_dict(): + await test_list_column_specs_async(request_type=dict) + + def test_list_column_specs_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3382,7 +3404,7 @@ def test_list_column_specs_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_column_specs), "__call__" + type(client.transport.list_column_specs), "__call__" ) as call: call.return_value = service.ListColumnSpecsResponse() @@ -3409,7 +3431,7 @@ async def test_list_column_specs_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_column_specs), "__call__" + type(client.transport.list_column_specs), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListColumnSpecsResponse() @@ -3432,7 +3454,7 @@ def test_list_column_specs_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_column_specs), "__call__" + type(client.transport.list_column_specs), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListColumnSpecsResponse() @@ -3466,7 +3488,7 @@ async def test_list_column_specs_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_column_specs), "__call__" + type(client.transport.list_column_specs), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListColumnSpecsResponse() @@ -3503,7 +3525,7 @@ def test_list_column_specs_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_column_specs), "__call__" + type(client.transport.list_column_specs), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -3543,7 +3565,7 @@ def test_list_column_specs_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_column_specs), "__call__" + type(client.transport.list_column_specs), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -3575,7 +3597,7 @@ async def test_list_column_specs_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_column_specs), + type(client.transport.list_column_specs), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -3614,7 +3636,7 @@ async def test_list_column_specs_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_column_specs), + type(client.transport.list_column_specs), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -3657,7 +3679,7 @@ def test_update_column_spec( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.update_column_spec), "__call__" + type(client.transport.update_column_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = gca_column_spec.ColumnSpec( @@ -3673,6 +3695,7 @@ def test_update_column_spec( assert args[0] == service.UpdateColumnSpecRequest() # Establish that the response is the type that we expect. + assert isinstance(response, gca_column_spec.ColumnSpec) assert response.name == "name_value" @@ -3687,18 +3710,20 @@ def test_update_column_spec_from_dict(): @pytest.mark.asyncio -async def test_update_column_spec_async(transport: str = "grpc_asyncio"): +async def test_update_column_spec_async( + transport: str = "grpc_asyncio", request_type=service.UpdateColumnSpecRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.UpdateColumnSpecRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.update_column_spec), "__call__" + type(client.transport.update_column_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -3713,7 +3738,7 @@ async def test_update_column_spec_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.UpdateColumnSpecRequest() # Establish that the response is the type that we expect. assert isinstance(response, gca_column_spec.ColumnSpec) @@ -3725,6 +3750,11 @@ async def test_update_column_spec_async(transport: str = "grpc_asyncio"): assert response.etag == "etag_value" +@pytest.mark.asyncio +async def test_update_column_spec_async_from_dict(): + await test_update_column_spec_async(request_type=dict) + + def test_update_column_spec_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3735,7 +3765,7 @@ def test_update_column_spec_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.update_column_spec), "__call__" + type(client.transport.update_column_spec), "__call__" ) as call: call.return_value = gca_column_spec.ColumnSpec() @@ -3764,7 +3794,7 @@ async def test_update_column_spec_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.update_column_spec), "__call__" + type(client.transport.update_column_spec), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( gca_column_spec.ColumnSpec() @@ -3789,7 +3819,7 @@ def test_update_column_spec_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.update_column_spec), "__call__" + type(client.transport.update_column_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = gca_column_spec.ColumnSpec() @@ -3826,7 +3856,7 @@ async def test_update_column_spec_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.update_column_spec), "__call__" + type(client.transport.update_column_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = gca_column_spec.ColumnSpec() @@ -3871,7 +3901,7 @@ def test_create_model(transport: str = "grpc", request_type=service.CreateModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_model), "__call__") as call: + with mock.patch.object(type(client.transport.create_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -3892,19 +3922,19 @@ def test_create_model_from_dict(): @pytest.mark.asyncio -async def test_create_model_async(transport: str = "grpc_asyncio"): +async def test_create_model_async( + transport: str = "grpc_asyncio", request_type=service.CreateModelRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.CreateModelRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -3916,12 +3946,17 @@ async def test_create_model_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.CreateModelRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_create_model_async_from_dict(): + await test_create_model_async(request_type=dict) + + def test_create_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3931,7 +3966,7 @@ def test_create_model_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_model), "__call__") as call: + with mock.patch.object(type(client.transport.create_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.create_model(request) @@ -3956,9 +3991,7 @@ async def test_create_model_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_model), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -3979,7 +4012,7 @@ def test_create_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_model), "__call__") as call: + with mock.patch.object(type(client.transport.create_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -4030,9 +4063,7 @@ async def test_create_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -4092,7 +4123,7 @@ def test_get_model(transport: str = "grpc", request_type=service.GetModelRequest request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_model), "__call__") as call: + with mock.patch.object(type(client.transport.get_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = model.Model( name="name_value", @@ -4113,6 +4144,7 @@ def test_get_model(transport: str = "grpc", request_type=service.GetModelRequest assert args[0] == service.GetModelRequest() # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) assert response.name == "name_value" @@ -4129,19 +4161,19 @@ def test_get_model_from_dict(): @pytest.mark.asyncio -async def test_get_model_async(transport: str = "grpc_asyncio"): +async def test_get_model_async( + transport: str = "grpc_asyncio", request_type=service.GetModelRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.GetModelRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( model.Model( @@ -4158,7 +4190,7 @@ async def test_get_model_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.GetModelRequest() # Establish that the response is the type that we expect. assert isinstance(response, model.Model) @@ -4172,6 +4204,11 @@ async def test_get_model_async(transport: str = "grpc_asyncio"): assert response.deployment_state == model.Model.DeploymentState.DEPLOYED +@pytest.mark.asyncio +async def test_get_model_async_from_dict(): + await test_get_model_async(request_type=dict) + + def test_get_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4181,7 +4218,7 @@ def test_get_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_model), "__call__") as call: + with mock.patch.object(type(client.transport.get_model), "__call__") as call: call.return_value = model.Model() client.get_model(request) @@ -4206,9 +4243,7 @@ async def test_get_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_model), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) await client.get_model(request) @@ -4227,7 +4262,7 @@ def test_get_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_model), "__call__") as call: + with mock.patch.object(type(client.transport.get_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = model.Model() @@ -4259,9 +4294,7 @@ async def test_get_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = model.Model() @@ -4300,7 +4333,7 @@ def test_list_models(transport: str = "grpc", request_type=service.ListModelsReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_models), "__call__") as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelsResponse( next_page_token="next_page_token_value", @@ -4315,6 +4348,7 @@ def test_list_models(transport: str = "grpc", request_type=service.ListModelsReq assert args[0] == service.ListModelsRequest() # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsPager) assert response.next_page_token == "next_page_token_value" @@ -4325,19 +4359,19 @@ def test_list_models_from_dict(): @pytest.mark.asyncio -async def test_list_models_async(transport: str = "grpc_asyncio"): +async def test_list_models_async( + transport: str = "grpc_asyncio", request_type=service.ListModelsRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ListModelsRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_models), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListModelsResponse(next_page_token="next_page_token_value",) @@ -4349,7 +4383,7 @@ async def test_list_models_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ListModelsRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListModelsAsyncPager) @@ -4357,6 +4391,11 @@ async def test_list_models_async(transport: str = "grpc_asyncio"): assert response.next_page_token == "next_page_token_value" +@pytest.mark.asyncio +async def test_list_models_async_from_dict(): + await test_list_models_async(request_type=dict) + + def test_list_models_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4366,7 +4405,7 @@ def test_list_models_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_models), "__call__") as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: call.return_value = service.ListModelsResponse() client.list_models(request) @@ -4391,9 +4430,7 @@ async def test_list_models_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_models), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListModelsResponse() ) @@ -4414,7 +4451,7 @@ def test_list_models_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_models), "__call__") as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelsResponse() @@ -4446,9 +4483,7 @@ async def test_list_models_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_models), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelsResponse() @@ -4483,7 +4518,7 @@ def test_list_models_pager(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_models), "__call__") as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListModelsResponse( @@ -4513,7 +4548,7 @@ def test_list_models_pages(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_models), "__call__") as call: + with mock.patch.object(type(client.transport.list_models), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListModelsResponse( @@ -4536,9 +4571,7 @@ async def test_list_models_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_models), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_models), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -4567,9 +4600,7 @@ async def test_list_models_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_models), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_models), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -4599,7 +4630,7 @@ def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_model), "__call__") as call: + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -4620,19 +4651,19 @@ def test_delete_model_from_dict(): @pytest.mark.asyncio -async def test_delete_model_async(transport: str = "grpc_asyncio"): +async def test_delete_model_async( + transport: str = "grpc_asyncio", request_type=service.DeleteModelRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.DeleteModelRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -4644,12 +4675,17 @@ async def test_delete_model_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.DeleteModelRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_delete_model_async_from_dict(): + await test_delete_model_async(request_type=dict) + + def test_delete_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4659,7 +4695,7 @@ def test_delete_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_model), "__call__") as call: + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.delete_model(request) @@ -4684,9 +4720,7 @@ async def test_delete_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -4707,7 +4741,7 @@ def test_delete_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_model), "__call__") as call: + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -4739,9 +4773,7 @@ async def test_delete_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -4782,7 +4814,7 @@ def test_deploy_model(transport: str = "grpc", request_type=service.DeployModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.deploy_model), "__call__") as call: + with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -4803,19 +4835,19 @@ def test_deploy_model_from_dict(): @pytest.mark.asyncio -async def test_deploy_model_async(transport: str = "grpc_asyncio"): +async def test_deploy_model_async( + transport: str = "grpc_asyncio", request_type=service.DeployModelRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.DeployModelRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.deploy_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -4827,12 +4859,17 @@ async def test_deploy_model_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.DeployModelRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_deploy_model_async_from_dict(): + await test_deploy_model_async(request_type=dict) + + def test_deploy_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4842,7 +4879,7 @@ def test_deploy_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.deploy_model), "__call__") as call: + with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.deploy_model(request) @@ -4867,9 +4904,7 @@ async def test_deploy_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.deploy_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -4890,7 +4925,7 @@ def test_deploy_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.deploy_model), "__call__") as call: + with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -4922,9 +4957,7 @@ async def test_deploy_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.deploy_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -4967,7 +5000,7 @@ def test_undeploy_model( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.undeploy_model), "__call__") as call: + with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -4988,19 +5021,19 @@ def test_undeploy_model_from_dict(): @pytest.mark.asyncio -async def test_undeploy_model_async(transport: str = "grpc_asyncio"): +async def test_undeploy_model_async( + transport: str = "grpc_asyncio", request_type=service.UndeployModelRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.UndeployModelRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.undeploy_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -5012,12 +5045,17 @@ async def test_undeploy_model_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.UndeployModelRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_undeploy_model_async_from_dict(): + await test_undeploy_model_async(request_type=dict) + + def test_undeploy_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -5027,7 +5065,7 @@ def test_undeploy_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.undeploy_model), "__call__") as call: + with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.undeploy_model(request) @@ -5052,9 +5090,7 @@ async def test_undeploy_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.undeploy_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -5075,7 +5111,7 @@ def test_undeploy_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.undeploy_model), "__call__") as call: + with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -5107,9 +5143,7 @@ async def test_undeploy_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.undeploy_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -5150,7 +5184,7 @@ def test_export_model(transport: str = "grpc", request_type=service.ExportModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_model), "__call__") as call: + with mock.patch.object(type(client.transport.export_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -5171,19 +5205,19 @@ def test_export_model_from_dict(): @pytest.mark.asyncio -async def test_export_model_async(transport: str = "grpc_asyncio"): +async def test_export_model_async( + transport: str = "grpc_asyncio", request_type=service.ExportModelRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ExportModelRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -5195,12 +5229,17 @@ async def test_export_model_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ExportModelRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_export_model_async_from_dict(): + await test_export_model_async(request_type=dict) + + def test_export_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -5210,7 +5249,7 @@ def test_export_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_model), "__call__") as call: + with mock.patch.object(type(client.transport.export_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.export_model(request) @@ -5235,9 +5274,7 @@ async def test_export_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_model), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -5258,7 +5295,7 @@ def test_export_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_model), "__call__") as call: + with mock.patch.object(type(client.transport.export_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -5309,9 +5346,7 @@ async def test_export_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_model), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -5374,7 +5409,7 @@ def test_export_evaluated_examples( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.export_evaluated_examples), "__call__" + type(client.transport.export_evaluated_examples), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -5396,18 +5431,20 @@ def test_export_evaluated_examples_from_dict(): @pytest.mark.asyncio -async def test_export_evaluated_examples_async(transport: str = "grpc_asyncio"): +async def test_export_evaluated_examples_async( + transport: str = "grpc_asyncio", request_type=service.ExportEvaluatedExamplesRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ExportEvaluatedExamplesRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.export_evaluated_examples), "__call__" + type(client.transport.export_evaluated_examples), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -5420,12 +5457,17 @@ async def test_export_evaluated_examples_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ExportEvaluatedExamplesRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_export_evaluated_examples_async_from_dict(): + await test_export_evaluated_examples_async(request_type=dict) + + def test_export_evaluated_examples_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -5436,7 +5478,7 @@ def test_export_evaluated_examples_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.export_evaluated_examples), "__call__" + type(client.transport.export_evaluated_examples), "__call__" ) as call: call.return_value = operations_pb2.Operation(name="operations/op") @@ -5463,7 +5505,7 @@ async def test_export_evaluated_examples_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.export_evaluated_examples), "__call__" + type(client.transport.export_evaluated_examples), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") @@ -5486,7 +5528,7 @@ def test_export_evaluated_examples_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.export_evaluated_examples), "__call__" + type(client.transport.export_evaluated_examples), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -5537,7 +5579,7 @@ async def test_export_evaluated_examples_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.export_evaluated_examples), "__call__" + type(client.transport.export_evaluated_examples), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -5599,7 +5641,7 @@ def test_get_model_evaluation( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_model_evaluation), "__call__" + type(client.transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = model_evaluation.ModelEvaluation( @@ -5621,6 +5663,7 @@ def test_get_model_evaluation( assert args[0] == service.GetModelEvaluationRequest() # Establish that the response is the type that we expect. + assert isinstance(response, model_evaluation.ModelEvaluation) assert response.name == "name_value" @@ -5637,18 +5680,20 @@ def test_get_model_evaluation_from_dict(): @pytest.mark.asyncio -async def test_get_model_evaluation_async(transport: str = "grpc_asyncio"): +async def test_get_model_evaluation_async( + transport: str = "grpc_asyncio", request_type=service.GetModelEvaluationRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.GetModelEvaluationRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_model_evaluation), "__call__" + type(client.transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -5666,7 +5711,7 @@ async def test_get_model_evaluation_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.GetModelEvaluationRequest() # Establish that the response is the type that we expect. assert isinstance(response, model_evaluation.ModelEvaluation) @@ -5680,6 +5725,11 @@ async def test_get_model_evaluation_async(transport: str = "grpc_asyncio"): assert response.evaluated_example_count == 2446 +@pytest.mark.asyncio +async def test_get_model_evaluation_async_from_dict(): + await test_get_model_evaluation_async(request_type=dict) + + def test_get_model_evaluation_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -5690,7 +5740,7 @@ def test_get_model_evaluation_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_model_evaluation), "__call__" + type(client.transport.get_model_evaluation), "__call__" ) as call: call.return_value = model_evaluation.ModelEvaluation() @@ -5717,7 +5767,7 @@ async def test_get_model_evaluation_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_model_evaluation), "__call__" + type(client.transport.get_model_evaluation), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( model_evaluation.ModelEvaluation() @@ -5740,7 +5790,7 @@ def test_get_model_evaluation_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_model_evaluation), "__call__" + type(client.transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = model_evaluation.ModelEvaluation() @@ -5774,7 +5824,7 @@ async def test_get_model_evaluation_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_model_evaluation), "__call__" + type(client.transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = model_evaluation.ModelEvaluation() @@ -5819,7 +5869,7 @@ def test_list_model_evaluations( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelEvaluationsResponse( @@ -5835,6 +5885,7 @@ def test_list_model_evaluations( assert args[0] == service.ListModelEvaluationsRequest() # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelEvaluationsPager) assert response.next_page_token == "next_page_token_value" @@ -5845,18 +5896,20 @@ def test_list_model_evaluations_from_dict(): @pytest.mark.asyncio -async def test_list_model_evaluations_async(transport: str = "grpc_asyncio"): +async def test_list_model_evaluations_async( + transport: str = "grpc_asyncio", request_type=service.ListModelEvaluationsRequest +): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = service.ListModelEvaluationsRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -5871,7 +5924,7 @@ async def test_list_model_evaluations_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == service.ListModelEvaluationsRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListModelEvaluationsAsyncPager) @@ -5879,6 +5932,11 @@ async def test_list_model_evaluations_async(transport: str = "grpc_asyncio"): assert response.next_page_token == "next_page_token_value" +@pytest.mark.asyncio +async def test_list_model_evaluations_async_from_dict(): + await test_list_model_evaluations_async(request_type=dict) + + def test_list_model_evaluations_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -5889,7 +5947,7 @@ def test_list_model_evaluations_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: call.return_value = service.ListModelEvaluationsResponse() @@ -5916,7 +5974,7 @@ async def test_list_model_evaluations_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListModelEvaluationsResponse() @@ -5939,7 +5997,7 @@ def test_list_model_evaluations_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelEvaluationsResponse() @@ -5973,7 +6031,7 @@ async def test_list_model_evaluations_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelEvaluationsResponse() @@ -6010,7 +6068,7 @@ def test_list_model_evaluations_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -6056,7 +6114,7 @@ def test_list_model_evaluations_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_model_evaluations), "__call__" + type(client.transport.list_model_evaluations), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -6094,7 +6152,7 @@ async def test_list_model_evaluations_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_model_evaluations), + type(client.transport.list_model_evaluations), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -6139,7 +6197,7 @@ async def test_list_model_evaluations_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_model_evaluations), + type(client.transport.list_model_evaluations), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -6211,7 +6269,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = AutoMlClient(transport=transport) - assert client._transport is transport + assert client.transport is transport def test_transport_get_channel(): @@ -6244,7 +6302,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client._transport, transports.AutoMlGrpcTransport,) + assert isinstance(client.transport, transports.AutoMlGrpcTransport,) def test_auto_ml_base_transport_error(): @@ -6366,7 +6424,7 @@ def test_auto_ml_host_no_port(): api_endpoint="automl.googleapis.com" ), ) - assert client._transport._host == "automl.googleapis.com:443" + assert client.transport._host == "automl.googleapis.com:443" def test_auto_ml_host_with_port(): @@ -6376,7 +6434,7 @@ def test_auto_ml_host_with_port(): api_endpoint="automl.googleapis.com:8000" ), ) - assert client._transport._host == "automl.googleapis.com:8000" + assert client.transport._host == "automl.googleapis.com:8000" def test_auto_ml_grpc_transport_channel(): @@ -6484,7 +6542,7 @@ def test_auto_ml_grpc_lro_client(): client = AutoMlClient( credentials=credentials.AnonymousCredentials(), transport="grpc", ) - transport = client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsClient,) @@ -6497,7 +6555,7 @@ def test_auto_ml_grpc_lro_async_client(): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", ) - transport = client._client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,) @@ -6506,12 +6564,44 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_column_spec_path(): +def test_annotation_spec_path(): project = "squid" location = "clam" dataset = "whelk" - table_spec = "octopus" - column_spec = "oyster" + annotation_spec = "octopus" + + expected = "projects/{project}/locations/{location}/datasets/{dataset}/annotationSpecs/{annotation_spec}".format( + project=project, + location=location, + dataset=dataset, + annotation_spec=annotation_spec, + ) + actual = AutoMlClient.annotation_spec_path( + project, location, dataset, annotation_spec + ) + assert expected == actual + + +def test_parse_annotation_spec_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "dataset": "cuttlefish", + "annotation_spec": "mussel", + } + path = AutoMlClient.annotation_spec_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_annotation_spec_path(path) + assert expected == actual + + +def test_column_spec_path(): + project = "winkle" + location = "nautilus" + dataset = "scallop" + table_spec = "abalone" + column_spec = "squid" expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}".format( project=project, @@ -6528,11 +6618,11 @@ def test_column_spec_path(): def test_parse_column_spec_path(): expected = { - "project": "nudibranch", - "location": "cuttlefish", - "dataset": "mussel", - "table_spec": "winkle", - "column_spec": "nautilus", + "project": "clam", + "location": "whelk", + "dataset": "octopus", + "table_spec": "oyster", + "column_spec": "nudibranch", } path = AutoMlClient.column_spec_path(**expected) @@ -6542,9 +6632,9 @@ def test_parse_column_spec_path(): def test_dataset_path(): - project = "squid" - location = "clam" - dataset = "whelk" + project = "cuttlefish" + location = "mussel" + dataset = "winkle" expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( project=project, location=location, dataset=dataset, @@ -6555,9 +6645,9 @@ def test_dataset_path(): def test_parse_dataset_path(): expected = { - "project": "octopus", - "location": "oyster", - "dataset": "nudibranch", + "project": "nautilus", + "location": "scallop", + "dataset": "abalone", } path = AutoMlClient.dataset_path(**expected) @@ -6591,11 +6681,43 @@ def test_parse_model_path(): assert expected == actual +def test_model_evaluation_path(): + project = "cuttlefish" + location = "mussel" + model = "winkle" + model_evaluation = "nautilus" + + expected = "projects/{project}/locations/{location}/models/{model}/modelEvaluations/{model_evaluation}".format( + project=project, + location=location, + model=model, + model_evaluation=model_evaluation, + ) + actual = AutoMlClient.model_evaluation_path( + project, location, model, model_evaluation + ) + assert expected == actual + + +def test_parse_model_evaluation_path(): + expected = { + "project": "scallop", + "location": "abalone", + "model": "squid", + "model_evaluation": "clam", + } + path = AutoMlClient.model_evaluation_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_model_evaluation_path(path) + assert expected == actual + + def test_table_spec_path(): - project = "squid" - location = "clam" - dataset = "whelk" - table_spec = "octopus" + project = "whelk" + location = "octopus" + dataset = "oyster" + table_spec = "nudibranch" expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( project=project, location=location, dataset=dataset, table_spec=table_spec, @@ -6606,10 +6728,10 @@ def test_table_spec_path(): def test_parse_table_spec_path(): expected = { - "project": "oyster", - "location": "nudibranch", - "dataset": "cuttlefish", - "table_spec": "mussel", + "project": "cuttlefish", + "location": "mussel", + "dataset": "winkle", + "table_spec": "nautilus", } path = AutoMlClient.table_spec_path(**expected) @@ -6618,6 +6740,107 @@ def test_parse_table_spec_path(): assert expected == actual +def test_common_billing_account_path(): + billing_account = "scallop" + + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = AutoMlClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = AutoMlClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "squid" + + expected = "folders/{folder}".format(folder=folder,) + actual = AutoMlClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = AutoMlClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "whelk" + + expected = "organizations/{organization}".format(organization=organization,) + actual = AutoMlClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = AutoMlClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "oyster" + + expected = "projects/{project}".format(project=project,) + actual = AutoMlClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = AutoMlClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "cuttlefish" + location = "mussel" + + expected = "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + actual = AutoMlClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = AutoMlClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = AutoMlClient.parse_common_location_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() diff --git a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py index 44c966c5..4a9c2a22 100644 --- a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py @@ -109,12 +109,12 @@ def test_prediction_service_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds - assert client._transport._host == "automl.googleapis.com:443" + assert client.transport._host == "automl.googleapis.com:443" def test_prediction_service_client_get_transport_class(): @@ -474,7 +474,7 @@ def test_predict( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.predict), "__call__") as call: + with mock.patch.object(type(client.transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = prediction_service.PredictResponse() @@ -487,6 +487,7 @@ def test_predict( assert args[0] == prediction_service.PredictRequest() # Establish that the response is the type that we expect. + assert isinstance(response, prediction_service.PredictResponse) @@ -495,17 +496,19 @@ def test_predict_from_dict(): @pytest.mark.asyncio -async def test_predict_async(transport: str = "grpc_asyncio"): +async def test_predict_async( + transport: str = "grpc_asyncio", request_type=prediction_service.PredictRequest +): client = PredictionServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = prediction_service.PredictRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._client._transport.predict), "__call__") as call: + with mock.patch.object(type(client.transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( prediction_service.PredictResponse() @@ -517,12 +520,17 @@ async def test_predict_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == prediction_service.PredictRequest() # Establish that the response is the type that we expect. assert isinstance(response, prediction_service.PredictResponse) +@pytest.mark.asyncio +async def test_predict_async_from_dict(): + await test_predict_async(request_type=dict) + + def test_predict_field_headers(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -532,7 +540,7 @@ def test_predict_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.predict), "__call__") as call: + with mock.patch.object(type(client.transport.predict), "__call__") as call: call.return_value = prediction_service.PredictResponse() client.predict(request) @@ -559,7 +567,7 @@ async def test_predict_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._client._transport.predict), "__call__") as call: + with mock.patch.object(type(client.transport.predict), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( prediction_service.PredictResponse() ) @@ -580,7 +588,7 @@ def test_predict_flattened(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.predict), "__call__") as call: + with mock.patch.object(type(client.transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = prediction_service.PredictResponse() @@ -631,7 +639,7 @@ async def test_predict_flattened_async(): ) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._client._transport.predict), "__call__") as call: + with mock.patch.object(type(client.transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = prediction_service.PredictResponse() @@ -693,7 +701,7 @@ def test_batch_predict( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.batch_predict), "__call__") as call: + with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -714,19 +722,19 @@ def test_batch_predict_from_dict(): @pytest.mark.asyncio -async def test_batch_predict_async(transport: str = "grpc_asyncio"): +async def test_batch_predict_async( + transport: str = "grpc_asyncio", request_type=prediction_service.BatchPredictRequest +): client = PredictionServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = prediction_service.BatchPredictRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.batch_predict), "__call__" - ) as call: + with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -738,12 +746,17 @@ async def test_batch_predict_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == prediction_service.BatchPredictRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_batch_predict_async_from_dict(): + await test_batch_predict_async(request_type=dict) + + def test_batch_predict_field_headers(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -753,7 +766,7 @@ def test_batch_predict_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.batch_predict), "__call__") as call: + with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.batch_predict(request) @@ -780,9 +793,7 @@ async def test_batch_predict_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.batch_predict), "__call__" - ) as call: + with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -803,7 +814,7 @@ def test_batch_predict_flattened(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.batch_predict), "__call__") as call: + with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -870,9 +881,7 @@ async def test_batch_predict_flattened_async(): ) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.batch_predict), "__call__" - ) as call: + with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -974,7 +983,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = PredictionServiceClient(transport=transport) - assert client._transport is transport + assert client.transport is transport def test_transport_get_channel(): @@ -1010,7 +1019,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client._transport, transports.PredictionServiceGrpcTransport,) + assert isinstance(client.transport, transports.PredictionServiceGrpcTransport,) def test_prediction_service_base_transport_error(): @@ -1110,7 +1119,7 @@ def test_prediction_service_host_no_port(): api_endpoint="automl.googleapis.com" ), ) - assert client._transport._host == "automl.googleapis.com:443" + assert client.transport._host == "automl.googleapis.com:443" def test_prediction_service_host_with_port(): @@ -1120,7 +1129,7 @@ def test_prediction_service_host_with_port(): api_endpoint="automl.googleapis.com:8000" ), ) - assert client._transport._host == "automl.googleapis.com:8000" + assert client.transport._host == "automl.googleapis.com:8000" def test_prediction_service_grpc_transport_channel(): @@ -1236,7 +1245,7 @@ def test_prediction_service_grpc_lro_client(): client = PredictionServiceClient( credentials=credentials.AnonymousCredentials(), transport="grpc", ) - transport = client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsClient,) @@ -1249,7 +1258,7 @@ def test_prediction_service_grpc_lro_async_client(): client = PredictionServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", ) - transport = client._client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,) @@ -1258,6 +1267,132 @@ def test_prediction_service_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client +def test_model_path(): + project = "squid" + location = "clam" + model = "whelk" + + expected = "projects/{project}/locations/{location}/models/{model}".format( + project=project, location=location, model=model, + ) + actual = PredictionServiceClient.model_path(project, location, model) + assert expected == actual + + +def test_parse_model_path(): + expected = { + "project": "octopus", + "location": "oyster", + "model": "nudibranch", + } + path = PredictionServiceClient.model_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_model_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = PredictionServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = PredictionServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + + expected = "folders/{folder}".format(folder=folder,) + actual = PredictionServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = PredictionServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + + expected = "organizations/{organization}".format(organization=organization,) + actual = PredictionServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = PredictionServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + + expected = "projects/{project}".format(project=project,) + actual = PredictionServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = PredictionServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + + expected = "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + actual = PredictionServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = PredictionServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_location_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() From b83d2c7e98a0d22bee82a8b8fb89c3b9b0cd342f Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 06:06:12 -0700 Subject: [PATCH 20/25] chore: upgrade to gapic-generator-python 0.35.6 PiperOrigin-RevId: 338489505 Source-Author: Google APIs Source-Date: Thu Oct 22 09:36:18 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: 4b34a0869404af9d83ae89952d28712a4d29eba6 Source-Link: https://github.com/googleapis/googleapis/commit/4b34a0869404af9d83ae89952d28712a4d29eba6 --- google/cloud/automl_v1/__init__.py | 4 +- .../services/auto_ml/async_client.py | 86 +- .../automl_v1/services/auto_ml/client.py | 118 +- .../services/auto_ml/transports/grpc.py | 14 +- .../prediction_service/async_client.py | 57 +- .../services/prediction_service/client.py | 102 +- .../prediction_service/transports/grpc.py | 14 +- google/cloud/automl_v1/types/data_items.py | 12 +- google/cloud/automl_v1/types/detection.py | 2 +- google/cloud/automl_v1/types/geometry.py | 2 +- .../services/auto_ml/async_client.py | 128 +-- .../automl_v1beta1/services/auto_ml/client.py | 118 +- .../services/auto_ml/transports/base.py | 24 +- .../services/auto_ml/transports/grpc.py | 14 +- .../prediction_service/async_client.py | 57 +- .../services/prediction_service/client.py | 102 +- .../prediction_service/transports/grpc.py | 14 +- .../automl_v1beta1/types/classification.py | 2 +- .../cloud/automl_v1beta1/types/data_items.py | 14 +- .../cloud/automl_v1beta1/types/data_stats.py | 4 +- .../cloud/automl_v1beta1/types/data_types.py | 2 +- .../cloud/automl_v1beta1/types/detection.py | 4 +- google/cloud/automl_v1beta1/types/geometry.py | 2 +- synth.metadata | 4 +- tests/unit/gapic/automl_v1/test_auto_ml.py | 784 +++++-------- .../automl_v1/test_prediction_service.py | 201 +--- .../unit/gapic/automl_v1beta1/test_auto_ml.py | 1007 +++++++---------- .../automl_v1beta1/test_prediction_service.py | 201 +--- 28 files changed, 911 insertions(+), 2182 deletions(-) diff --git a/google/cloud/automl_v1/__init__.py b/google/cloud/automl_v1/__init__.py index b5f76f81..6f22bb65 100644 --- a/google/cloud/automl_v1/__init__.py +++ b/google/cloud/automl_v1/__init__.py @@ -104,6 +104,7 @@ __all__ = ( "AnnotationPayload", "AnnotationSpec", + "AutoMlClient", "BatchPredictInputConfig", "BatchPredictOperationMetadata", "BatchPredictOutputConfig", @@ -164,7 +165,6 @@ "OutputConfig", "PredictRequest", "PredictResponse", - "PredictionServiceClient", "TextClassificationDatasetMetadata", "TextClassificationModelMetadata", "TextExtractionAnnotation", @@ -185,5 +185,5 @@ "UndeployModelRequest", "UpdateDatasetRequest", "UpdateModelRequest", - "AutoMlClient", + "PredictionServiceClient", ) diff --git a/google/cloud/automl_v1/services/auto_ml/async_client.py b/google/cloud/automl_v1/services/auto_ml/async_client.py index 254f5cc5..a2cc6f22 100644 --- a/google/cloud/automl_v1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1/services/auto_ml/async_client.py @@ -79,46 +79,14 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT - annotation_spec_path = staticmethod(AutoMlClient.annotation_spec_path) - parse_annotation_spec_path = staticmethod(AutoMlClient.parse_annotation_spec_path) dataset_path = staticmethod(AutoMlClient.dataset_path) parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) model_path = staticmethod(AutoMlClient.model_path) parse_model_path = staticmethod(AutoMlClient.parse_model_path) - model_evaluation_path = staticmethod(AutoMlClient.model_evaluation_path) - parse_model_evaluation_path = staticmethod(AutoMlClient.parse_model_evaluation_path) - - common_billing_account_path = staticmethod(AutoMlClient.common_billing_account_path) - parse_common_billing_account_path = staticmethod( - AutoMlClient.parse_common_billing_account_path - ) - - common_folder_path = staticmethod(AutoMlClient.common_folder_path) - parse_common_folder_path = staticmethod(AutoMlClient.parse_common_folder_path) - - common_organization_path = staticmethod(AutoMlClient.common_organization_path) - parse_common_organization_path = staticmethod( - AutoMlClient.parse_common_organization_path - ) - - common_project_path = staticmethod(AutoMlClient.common_project_path) - parse_common_project_path = staticmethod(AutoMlClient.parse_common_project_path) - - common_location_path = staticmethod(AutoMlClient.common_location_path) - parse_common_location_path = staticmethod(AutoMlClient.parse_common_location_path) from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file - @property - def transport(self) -> AutoMlTransport: - """Return the transport used by the client instance. - - Returns: - AutoMlTransport: The transport used by the client instance. - """ - return self._client.transport - get_transport_class = functools.partial( type(AutoMlClient).get_transport_class, type(AutoMlClient) ) @@ -219,8 +187,7 @@ async def create_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, dataset]) - if request is not None and has_flattened_params: + if request is not None and any([parent, dataset]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -303,8 +270,7 @@ async def get_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -386,8 +352,7 @@ async def list_datasets( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent]) - if request is not None and has_flattened_params: + if request is not None and any([parent]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -481,8 +446,7 @@ async def update_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([dataset, update_mask]) - if request is not None and has_flattened_params: + if request is not None and any([dataset, update_mask]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -576,8 +540,7 @@ async def delete_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -697,8 +660,7 @@ async def import_data( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name, input_config]) - if request is not None and has_flattened_params: + if request is not None and any([name, input_config]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -804,8 +766,7 @@ async def export_data( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name, output_config]) - if request is not None and has_flattened_params: + if request is not None and any([name, output_config]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -884,8 +845,7 @@ async def get_annotation_spec( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -978,8 +938,7 @@ async def create_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, model]) - if request is not None and has_flattened_params: + if request is not None and any([parent, model]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1059,8 +1018,7 @@ async def get_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1142,8 +1100,7 @@ async def list_models( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent]) - if request is not None and has_flattened_params: + if request is not None and any([parent]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1246,8 +1203,7 @@ async def delete_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1341,8 +1297,7 @@ async def update_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([model, update_mask]) - if request is not None and has_flattened_params: + if request is not None and any([model, update_mask]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1446,8 +1401,7 @@ async def deploy_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1549,8 +1503,7 @@ async def undeploy_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1660,8 +1613,7 @@ async def export_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name, output_config]) - if request is not None and has_flattened_params: + if request is not None and any([name, output_config]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1740,8 +1692,7 @@ async def get_model_evaluation( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1844,8 +1795,7 @@ async def list_model_evaluations( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, filter]) - if request is not None and has_flattened_params: + if request is not None and any([parent, filter]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." diff --git a/google/cloud/automl_v1/services/auto_ml/client.py b/google/cloud/automl_v1/services/auto_ml/client.py index 0b860787..3765ac0b 100644 --- a/google/cloud/automl_v1/services/auto_ml/client.py +++ b/google/cloud/automl_v1/services/auto_ml/client.py @@ -163,36 +163,6 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file - @property - def transport(self) -> AutoMlTransport: - """Return the transport used by the client instance. - - Returns: - AutoMlTransport: The transport used by the client instance. - """ - return self._transport - - @staticmethod - def annotation_spec_path( - project: str, location: str, dataset: str, annotation_spec: str, - ) -> str: - """Return a fully-qualified annotation_spec string.""" - return "projects/{project}/locations/{location}/datasets/{dataset}/annotationSpecs/{annotation_spec}".format( - project=project, - location=location, - dataset=dataset, - annotation_spec=annotation_spec, - ) - - @staticmethod - def parse_annotation_spec_path(path: str) -> Dict[str, str]: - """Parse a annotation_spec path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)/datasets/(?P.+?)/annotationSpecs/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - @staticmethod def dataset_path(project: str, location: str, dataset: str,) -> str: """Return a fully-qualified dataset string.""" @@ -225,86 +195,6 @@ def parse_model_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} - @staticmethod - def model_evaluation_path( - project: str, location: str, model: str, model_evaluation: str, - ) -> str: - """Return a fully-qualified model_evaluation string.""" - return "projects/{project}/locations/{location}/models/{model}/modelEvaluations/{model_evaluation}".format( - project=project, - location=location, - model=model, - model_evaluation=model_evaluation, - ) - - @staticmethod - def parse_model_evaluation_path(path: str) -> Dict[str, str]: - """Parse a model_evaluation path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)/models/(?P.+?)/modelEvaluations/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path(billing_account: str,) -> str: - """Return a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder,) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization,) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" - return "projects/{project}".format(project=project,) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - def __init__( self, *, @@ -340,10 +230,10 @@ def __init__( not provided, the default SSL client certificate will be used if present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: diff --git a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py index cc627573..b957e5cd 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/grpc.py @@ -111,10 +111,10 @@ def __init__( for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -243,8 +243,12 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. """ + # Return the channel from cache. return self._grpc_channel @property diff --git a/google/cloud/automl_v1/services/prediction_service/async_client.py b/google/cloud/automl_v1/services/prediction_service/async_client.py index 7f922fb3..d77836a0 100644 --- a/google/cloud/automl_v1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1/services/prediction_service/async_client.py @@ -53,50 +53,9 @@ class PredictionServiceAsyncClient: DEFAULT_ENDPOINT = PredictionServiceClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = PredictionServiceClient.DEFAULT_MTLS_ENDPOINT - model_path = staticmethod(PredictionServiceClient.model_path) - parse_model_path = staticmethod(PredictionServiceClient.parse_model_path) - - common_billing_account_path = staticmethod( - PredictionServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - PredictionServiceClient.parse_common_billing_account_path - ) - - common_folder_path = staticmethod(PredictionServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - PredictionServiceClient.parse_common_folder_path - ) - - common_organization_path = staticmethod( - PredictionServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - PredictionServiceClient.parse_common_organization_path - ) - - common_project_path = staticmethod(PredictionServiceClient.common_project_path) - parse_common_project_path = staticmethod( - PredictionServiceClient.parse_common_project_path - ) - - common_location_path = staticmethod(PredictionServiceClient.common_location_path) - parse_common_location_path = staticmethod( - PredictionServiceClient.parse_common_location_path - ) - from_service_account_file = PredictionServiceClient.from_service_account_file from_service_account_json = from_service_account_file - @property - def transport(self) -> PredictionServiceTransport: - """Return the transport used by the client instance. - - Returns: - PredictionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - get_transport_class = functools.partial( type(PredictionServiceClient).get_transport_class, type(PredictionServiceClient) ) @@ -266,8 +225,7 @@ async def predict( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name, payload, params]) - if request is not None and has_flattened_params: + if request is not None and any([name, payload, params]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -282,9 +240,8 @@ async def predict( request.name = name if payload is not None: request.payload = payload - - if params: - request.params.update(params) + if params is not None: + request.params = params # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -472,8 +429,7 @@ async def batch_predict( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name, input_config, output_config, params]) - if request is not None and has_flattened_params: + if request is not None and any([name, input_config, output_config, params]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -490,9 +446,8 @@ async def batch_predict( request.input_config = input_config if output_config is not None: request.output_config = output_config - - if params: - request.params.update(params) + if params is not None: + request.params = params # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/automl_v1/services/prediction_service/client.py b/google/cloud/automl_v1/services/prediction_service/client.py index a56b5a30..d2c1971a 100644 --- a/google/cloud/automl_v1/services/prediction_service/client.py +++ b/google/cloud/automl_v1/services/prediction_service/client.py @@ -141,90 +141,6 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file - @property - def transport(self) -> PredictionServiceTransport: - """Return the transport used by the client instance. - - Returns: - PredictionServiceTransport: The transport used by the client instance. - """ - return self._transport - - @staticmethod - def model_path(project: str, location: str, model: str,) -> str: - """Return a fully-qualified model string.""" - return "projects/{project}/locations/{location}/models/{model}".format( - project=project, location=location, model=model, - ) - - @staticmethod - def parse_model_path(path: str) -> Dict[str, str]: - """Parse a model path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)/models/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path(billing_account: str,) -> str: - """Return a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder,) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization,) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" - return "projects/{project}".format(project=project,) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - def __init__( self, *, @@ -260,10 +176,10 @@ def __init__( not provided, the default SSL client certificate will be used if present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -480,9 +396,8 @@ def predict( request.name = name if payload is not None: request.payload = payload - - if params: - request.params.update(params) + if params is not None: + request.params = params # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -689,9 +604,8 @@ def batch_predict( request.input_config = input_config if output_config is not None: request.output_config = output_config - - if params: - request.params.update(params) + if params is not None: + request.params = params # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py index 17c81f49..9a2c8e9b 100644 --- a/google/cloud/automl_v1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1/services/prediction_service/transports/grpc.py @@ -94,10 +94,10 @@ def __init__( for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -226,8 +226,12 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. """ + # Return the channel from cache. return self._grpc_channel @property diff --git a/google/cloud/automl_v1/types/data_items.py b/google/cloud/automl_v1/types/data_items.py index 554ed762..51ccc477 100644 --- a/google/cloud/automl_v1/types/data_items.py +++ b/google/cloud/automl_v1/types/data_items.py @@ -186,12 +186,12 @@ class TextSegmentType(proto.Enum): input_config = proto.Field(proto.MESSAGE, number=1, message=io.DocumentInputConfig,) - document_text = proto.Field(proto.MESSAGE, number=2, message="TextSnippet",) + document_text = proto.Field(proto.MESSAGE, number=2, message=TextSnippet,) layout = proto.RepeatedField(proto.MESSAGE, number=3, message=Layout,) document_dimensions = proto.Field( - proto.MESSAGE, number=4, message="DocumentDimensions", + proto.MESSAGE, number=4, message=DocumentDimensions, ) page_count = proto.Field(proto.INT32, number=5) @@ -209,15 +209,13 @@ class ExamplePayload(proto.Message): Example document. """ - image = proto.Field(proto.MESSAGE, number=1, oneof="payload", message="Image",) + image = proto.Field(proto.MESSAGE, number=1, oneof="payload", message=Image,) text_snippet = proto.Field( - proto.MESSAGE, number=2, oneof="payload", message="TextSnippet", + proto.MESSAGE, number=2, oneof="payload", message=TextSnippet, ) - document = proto.Field( - proto.MESSAGE, number=4, oneof="payload", message="Document", - ) + document = proto.Field(proto.MESSAGE, number=4, oneof="payload", message=Document,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/automl_v1/types/detection.py b/google/cloud/automl_v1/types/detection.py index 69ca1d54..6eab690c 100644 --- a/google/cloud/automl_v1/types/detection.py +++ b/google/cloud/automl_v1/types/detection.py @@ -128,7 +128,7 @@ class ImageObjectDetectionEvaluationMetrics(proto.Message): evaluated_bounding_box_count = proto.Field(proto.INT32, number=1) bounding_box_metrics_entries = proto.RepeatedField( - proto.MESSAGE, number=2, message="BoundingBoxMetricsEntry", + proto.MESSAGE, number=2, message=BoundingBoxMetricsEntry, ) bounding_box_mean_average_precision = proto.Field(proto.FLOAT, number=3) diff --git a/google/cloud/automl_v1/types/geometry.py b/google/cloud/automl_v1/types/geometry.py index 07c22dd9..f459ca52 100644 --- a/google/cloud/automl_v1/types/geometry.py +++ b/google/cloud/automl_v1/types/geometry.py @@ -55,7 +55,7 @@ class BoundingPoly(proto.Message): """ normalized_vertices = proto.RepeatedField( - proto.MESSAGE, number=2, message="NormalizedVertex", + proto.MESSAGE, number=2, message=NormalizedVertex, ) diff --git a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py index cd2c4388..b7a10974 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/async_client.py @@ -87,50 +87,18 @@ class AutoMlAsyncClient: DEFAULT_ENDPOINT = AutoMlClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AutoMlClient.DEFAULT_MTLS_ENDPOINT - annotation_spec_path = staticmethod(AutoMlClient.annotation_spec_path) - parse_annotation_spec_path = staticmethod(AutoMlClient.parse_annotation_spec_path) column_spec_path = staticmethod(AutoMlClient.column_spec_path) parse_column_spec_path = staticmethod(AutoMlClient.parse_column_spec_path) dataset_path = staticmethod(AutoMlClient.dataset_path) parse_dataset_path = staticmethod(AutoMlClient.parse_dataset_path) model_path = staticmethod(AutoMlClient.model_path) parse_model_path = staticmethod(AutoMlClient.parse_model_path) - model_evaluation_path = staticmethod(AutoMlClient.model_evaluation_path) - parse_model_evaluation_path = staticmethod(AutoMlClient.parse_model_evaluation_path) table_spec_path = staticmethod(AutoMlClient.table_spec_path) parse_table_spec_path = staticmethod(AutoMlClient.parse_table_spec_path) - common_billing_account_path = staticmethod(AutoMlClient.common_billing_account_path) - parse_common_billing_account_path = staticmethod( - AutoMlClient.parse_common_billing_account_path - ) - - common_folder_path = staticmethod(AutoMlClient.common_folder_path) - parse_common_folder_path = staticmethod(AutoMlClient.parse_common_folder_path) - - common_organization_path = staticmethod(AutoMlClient.common_organization_path) - parse_common_organization_path = staticmethod( - AutoMlClient.parse_common_organization_path - ) - - common_project_path = staticmethod(AutoMlClient.common_project_path) - parse_common_project_path = staticmethod(AutoMlClient.parse_common_project_path) - - common_location_path = staticmethod(AutoMlClient.common_location_path) - parse_common_location_path = staticmethod(AutoMlClient.parse_common_location_path) - from_service_account_file = AutoMlClient.from_service_account_file from_service_account_json = from_service_account_file - @property - def transport(self) -> AutoMlTransport: - """Return the transport used by the client instance. - - Returns: - AutoMlTransport: The transport used by the client instance. - """ - return self._client.transport - get_transport_class = functools.partial( type(AutoMlClient).get_transport_class, type(AutoMlClient) ) @@ -228,8 +196,7 @@ async def create_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, dataset]) - if request is not None and has_flattened_params: + if request is not None and any([parent, dataset]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -304,8 +271,7 @@ async def get_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -328,7 +294,7 @@ async def get_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -387,8 +353,7 @@ async def list_datasets( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent]) - if request is not None and has_flattened_params: + if request is not None and any([parent]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -411,7 +376,7 @@ async def list_datasets( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -475,8 +440,7 @@ async def update_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([dataset]) - if request is not None and has_flattened_params: + if request is not None and any([dataset]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -568,8 +532,7 @@ async def delete_dataset( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -592,7 +555,7 @@ async def delete_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -689,8 +652,7 @@ async def import_data( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name, input_config]) - if request is not None and has_flattened_params: + if request is not None and any([name, input_config]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -796,8 +758,7 @@ async def export_data( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name, output_config]) - if request is not None and has_flattened_params: + if request is not None and any([name, output_config]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -876,8 +837,7 @@ async def get_annotation_spec( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -900,7 +860,7 @@ async def get_annotation_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -965,8 +925,7 @@ async def get_table_spec( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -989,7 +948,7 @@ async def get_table_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1048,8 +1007,7 @@ async def list_table_specs( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent]) - if request is not None and has_flattened_params: + if request is not None and any([parent]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1072,7 +1030,7 @@ async def list_table_specs( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1143,8 +1101,7 @@ async def update_table_spec( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([table_spec]) - if request is not None and has_flattened_params: + if request is not None and any([table_spec]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1220,8 +1177,7 @@ async def get_column_spec( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1244,7 +1200,7 @@ async def get_column_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1303,8 +1259,7 @@ async def list_column_specs( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent]) - if request is not None and has_flattened_params: + if request is not None and any([parent]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1327,7 +1282,7 @@ async def list_column_specs( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1392,8 +1347,7 @@ async def update_column_spec( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([column_spec]) - if request is not None and has_flattened_params: + if request is not None and any([column_spec]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1480,8 +1434,7 @@ async def create_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, model]) - if request is not None and has_flattened_params: + if request is not None and any([parent, model]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1561,8 +1514,7 @@ async def get_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1585,7 +1537,7 @@ async def get_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1644,8 +1596,7 @@ async def list_models( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent]) - if request is not None and has_flattened_params: + if request is not None and any([parent]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1668,7 +1619,7 @@ async def list_models( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1748,8 +1699,7 @@ async def delete_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1772,7 +1722,7 @@ async def delete_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1865,8 +1815,7 @@ async def deploy_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -1968,8 +1917,7 @@ async def undeploy_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -2080,8 +2028,7 @@ async def export_model( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name, output_config]) - if request is not None and has_flattened_params: + if request is not None and any([name, output_config]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -2199,8 +2146,7 @@ async def export_evaluated_examples( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name, output_config]) - if request is not None and has_flattened_params: + if request is not None and any([name, output_config]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -2279,8 +2225,7 @@ async def get_model_evaluation( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: + if request is not None and any([name]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -2303,7 +2248,7 @@ async def get_model_evaluation( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -2365,8 +2310,7 @@ async def list_model_evaluations( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent]) - if request is not None and has_flattened_params: + if request is not None and any([parent]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." diff --git a/google/cloud/automl_v1beta1/services/auto_ml/client.py b/google/cloud/automl_v1beta1/services/auto_ml/client.py index a930910e..6ae4f4c2 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/client.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/client.py @@ -171,36 +171,6 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file - @property - def transport(self) -> AutoMlTransport: - """Return the transport used by the client instance. - - Returns: - AutoMlTransport: The transport used by the client instance. - """ - return self._transport - - @staticmethod - def annotation_spec_path( - project: str, location: str, dataset: str, annotation_spec: str, - ) -> str: - """Return a fully-qualified annotation_spec string.""" - return "projects/{project}/locations/{location}/datasets/{dataset}/annotationSpecs/{annotation_spec}".format( - project=project, - location=location, - dataset=dataset, - annotation_spec=annotation_spec, - ) - - @staticmethod - def parse_annotation_spec_path(path: str) -> Dict[str, str]: - """Parse a annotation_spec path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)/datasets/(?P.+?)/annotationSpecs/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - @staticmethod def column_spec_path( project: str, location: str, dataset: str, table_spec: str, column_spec: str, @@ -255,27 +225,6 @@ def parse_model_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} - @staticmethod - def model_evaluation_path( - project: str, location: str, model: str, model_evaluation: str, - ) -> str: - """Return a fully-qualified model_evaluation string.""" - return "projects/{project}/locations/{location}/models/{model}/modelEvaluations/{model_evaluation}".format( - project=project, - location=location, - model=model, - model_evaluation=model_evaluation, - ) - - @staticmethod - def parse_model_evaluation_path(path: str) -> Dict[str, str]: - """Parse a model_evaluation path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)/models/(?P.+?)/modelEvaluations/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - @staticmethod def table_spec_path( project: str, location: str, dataset: str, table_spec: str, @@ -294,65 +243,6 @@ def parse_table_spec_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} - @staticmethod - def common_billing_account_path(billing_account: str,) -> str: - """Return a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder,) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization,) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" - return "projects/{project}".format(project=project,) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - def __init__( self, *, @@ -388,10 +278,10 @@ def __init__( not provided, the default SSL client certificate will be used if present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py index 63f0601f..642c9f7b 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/base.py @@ -125,7 +125,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -138,7 +138,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -154,7 +154,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -173,7 +173,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -186,7 +186,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -199,7 +199,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -215,7 +215,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -228,7 +228,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -247,7 +247,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -260,7 +260,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -273,7 +273,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -300,7 +300,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py index 9c8c1580..a8cb2fd7 100644 --- a/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/auto_ml/transports/grpc.py @@ -114,10 +114,10 @@ def __init__( for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -246,8 +246,12 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. """ + # Return the channel from cache. return self._grpc_channel @property diff --git a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py index b1eadd8e..c204325b 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/async_client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/async_client.py @@ -53,50 +53,9 @@ class PredictionServiceAsyncClient: DEFAULT_ENDPOINT = PredictionServiceClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = PredictionServiceClient.DEFAULT_MTLS_ENDPOINT - model_path = staticmethod(PredictionServiceClient.model_path) - parse_model_path = staticmethod(PredictionServiceClient.parse_model_path) - - common_billing_account_path = staticmethod( - PredictionServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - PredictionServiceClient.parse_common_billing_account_path - ) - - common_folder_path = staticmethod(PredictionServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - PredictionServiceClient.parse_common_folder_path - ) - - common_organization_path = staticmethod( - PredictionServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - PredictionServiceClient.parse_common_organization_path - ) - - common_project_path = staticmethod(PredictionServiceClient.common_project_path) - parse_common_project_path = staticmethod( - PredictionServiceClient.parse_common_project_path - ) - - common_location_path = staticmethod(PredictionServiceClient.common_location_path) - parse_common_location_path = staticmethod( - PredictionServiceClient.parse_common_location_path - ) - from_service_account_file = PredictionServiceClient.from_service_account_file from_service_account_json = from_service_account_file - @property - def transport(self) -> PredictionServiceTransport: - """Return the transport used by the client instance. - - Returns: - PredictionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - get_transport_class = functools.partial( type(PredictionServiceClient).get_transport_class, type(PredictionServiceClient) ) @@ -242,8 +201,7 @@ async def predict( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name, payload, params]) - if request is not None and has_flattened_params: + if request is not None and any([name, payload, params]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -258,9 +216,8 @@ async def predict( request.name = name if payload is not None: request.payload = payload - - if params: - request.params.update(params) + if params is not None: + request.params = params # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -444,8 +401,7 @@ async def batch_predict( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([name, input_config, output_config, params]) - if request is not None and has_flattened_params: + if request is not None and any([name, input_config, output_config, params]): raise ValueError( "If the `request` argument is set, then none of " "the individual field arguments should be set." @@ -462,9 +418,8 @@ async def batch_predict( request.input_config = input_config if output_config is not None: request.output_config = output_config - - if params: - request.params.update(params) + if params is not None: + request.params = params # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/automl_v1beta1/services/prediction_service/client.py b/google/cloud/automl_v1beta1/services/prediction_service/client.py index 7508e83a..78ec510c 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/client.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/client.py @@ -141,90 +141,6 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file - @property - def transport(self) -> PredictionServiceTransport: - """Return the transport used by the client instance. - - Returns: - PredictionServiceTransport: The transport used by the client instance. - """ - return self._transport - - @staticmethod - def model_path(project: str, location: str, model: str,) -> str: - """Return a fully-qualified model string.""" - return "projects/{project}/locations/{location}/models/{model}".format( - project=project, location=location, model=model, - ) - - @staticmethod - def parse_model_path(path: str) -> Dict[str, str]: - """Parse a model path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)/models/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path(billing_account: str,) -> str: - """Return a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder,) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization,) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" - return "projects/{project}".format(project=project,) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - def __init__( self, *, @@ -260,10 +176,10 @@ def __init__( not provided, the default SSL client certificate will be used if present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not set, no client certificate will be used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -456,9 +372,8 @@ def predict( request.name = name if payload is not None: request.payload = payload - - if params: - request.params.update(params) + if params is not None: + request.params = params # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -661,9 +576,8 @@ def batch_predict( request.input_config = input_config if output_config is not None: request.output_config = output_config - - if params: - request.params.update(params) + if params is not None: + request.params = params # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py index 8d8225e1..3c484247 100644 --- a/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py +++ b/google/cloud/automl_v1beta1/services/prediction_service/transports/grpc.py @@ -94,10 +94,10 @@ def __init__( for grpc channel. It is ignored if ``channel`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -226,8 +226,12 @@ def create_channel( @property def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service. + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. """ + # Return the channel from cache. return self._grpc_channel @property diff --git a/google/cloud/automl_v1beta1/types/classification.py b/google/cloud/automl_v1beta1/types/classification.py index b9f21ba3..4b5e5a2a 100644 --- a/google/cloud/automl_v1beta1/types/classification.py +++ b/google/cloud/automl_v1beta1/types/classification.py @@ -99,7 +99,7 @@ class VideoClassificationAnnotation(proto.Message): type_ = proto.Field(proto.STRING, number=1) classification_annotation = proto.Field( - proto.MESSAGE, number=2, message="ClassificationAnnotation", + proto.MESSAGE, number=2, message=ClassificationAnnotation, ) time_segment = proto.Field(proto.MESSAGE, number=3, message=temporal.TimeSegment,) diff --git a/google/cloud/automl_v1beta1/types/data_items.py b/google/cloud/automl_v1beta1/types/data_items.py index eff58bee..4e0037b0 100644 --- a/google/cloud/automl_v1beta1/types/data_items.py +++ b/google/cloud/automl_v1beta1/types/data_items.py @@ -195,12 +195,12 @@ class TextSegmentType(proto.Enum): input_config = proto.Field(proto.MESSAGE, number=1, message=io.DocumentInputConfig,) - document_text = proto.Field(proto.MESSAGE, number=2, message="TextSnippet",) + document_text = proto.Field(proto.MESSAGE, number=2, message=TextSnippet,) layout = proto.RepeatedField(proto.MESSAGE, number=3, message=Layout,) document_dimensions = proto.Field( - proto.MESSAGE, number=4, message="DocumentDimensions", + proto.MESSAGE, number=4, message=DocumentDimensions, ) page_count = proto.Field(proto.INT32, number=5) @@ -247,17 +247,15 @@ class ExamplePayload(proto.Message): Example relational table row. """ - image = proto.Field(proto.MESSAGE, number=1, oneof="payload", message="Image",) + image = proto.Field(proto.MESSAGE, number=1, oneof="payload", message=Image,) text_snippet = proto.Field( - proto.MESSAGE, number=2, oneof="payload", message="TextSnippet", + proto.MESSAGE, number=2, oneof="payload", message=TextSnippet, ) - document = proto.Field( - proto.MESSAGE, number=4, oneof="payload", message="Document", - ) + document = proto.Field(proto.MESSAGE, number=4, oneof="payload", message=Document,) - row = proto.Field(proto.MESSAGE, number=3, oneof="payload", message="Row",) + row = proto.Field(proto.MESSAGE, number=3, oneof="payload", message=Row,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/automl_v1beta1/types/data_stats.py b/google/cloud/automl_v1beta1/types/data_stats.py index 75a9dc38..4405185f 100644 --- a/google/cloud/automl_v1beta1/types/data_stats.py +++ b/google/cloud/automl_v1beta1/types/data_stats.py @@ -210,7 +210,7 @@ class ArrayStats(proto.Message): depends on the element type of the array. """ - member_stats = proto.Field(proto.MESSAGE, number=2, message="DataStats",) + member_stats = proto.Field(proto.MESSAGE, number=2, message=DataStats,) class StructStats(proto.Message): @@ -224,7 +224,7 @@ class StructStats(proto.Message): """ field_stats = proto.MapField( - proto.STRING, proto.MESSAGE, number=1, message="DataStats", + proto.STRING, proto.MESSAGE, number=1, message=DataStats, ) diff --git a/google/cloud/automl_v1beta1/types/data_types.py b/google/cloud/automl_v1beta1/types/data_types.py index 6faa598b..e2a3152e 100644 --- a/google/cloud/automl_v1beta1/types/data_types.py +++ b/google/cloud/automl_v1beta1/types/data_types.py @@ -105,7 +105,7 @@ class StructType(proto.Message): mutable. """ - fields = proto.MapField(proto.STRING, proto.MESSAGE, number=1, message="DataType",) + fields = proto.MapField(proto.STRING, proto.MESSAGE, number=1, message=DataType,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/automl_v1beta1/types/detection.py b/google/cloud/automl_v1beta1/types/detection.py index c14a1cb5..3f3339ab 100644 --- a/google/cloud/automl_v1beta1/types/detection.py +++ b/google/cloud/automl_v1beta1/types/detection.py @@ -171,7 +171,7 @@ class ImageObjectDetectionEvaluationMetrics(proto.Message): evaluated_bounding_box_count = proto.Field(proto.INT32, number=1) bounding_box_metrics_entries = proto.RepeatedField( - proto.MESSAGE, number=2, message="BoundingBoxMetricsEntry", + proto.MESSAGE, number=2, message=BoundingBoxMetricsEntry, ) bounding_box_mean_average_precision = proto.Field(proto.FLOAT, number=3) @@ -208,7 +208,7 @@ class VideoObjectTrackingEvaluationMetrics(proto.Message): evaluated_bounding_box_count = proto.Field(proto.INT32, number=2) bounding_box_metrics_entries = proto.RepeatedField( - proto.MESSAGE, number=4, message="BoundingBoxMetricsEntry", + proto.MESSAGE, number=4, message=BoundingBoxMetricsEntry, ) bounding_box_mean_average_precision = proto.Field(proto.FLOAT, number=6) diff --git a/google/cloud/automl_v1beta1/types/geometry.py b/google/cloud/automl_v1beta1/types/geometry.py index f64a477f..7a463691 100644 --- a/google/cloud/automl_v1beta1/types/geometry.py +++ b/google/cloud/automl_v1beta1/types/geometry.py @@ -56,7 +56,7 @@ class BoundingPoly(proto.Message): """ normalized_vertices = proto.RepeatedField( - proto.MESSAGE, number=2, message="NormalizedVertex", + proto.MESSAGE, number=2, message=NormalizedVertex, ) diff --git a/synth.metadata b/synth.metadata index 51c12757..35ddbf7c 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "c7331b75b0b7bbd614373b7d37085db1c80dd4be", - "internalRef": "338157137" + "sha": "4b34a0869404af9d83ae89952d28712a4d29eba6", + "internalRef": "338489505" } }, { diff --git a/tests/unit/gapic/automl_v1/test_auto_ml.py b/tests/unit/gapic/automl_v1/test_auto_ml.py index 85e68e74..a11480cd 100644 --- a/tests/unit/gapic/automl_v1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1/test_auto_ml.py @@ -107,12 +107,12 @@ def test_auto_ml_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client.transport._credentials == creds + assert client._transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client.transport._credentials == creds + assert client._transport._credentials == creds - assert client.transport._host == "automl.googleapis.com:443" + assert client._transport._host == "automl.googleapis.com:443" def test_auto_ml_client_get_transport_class(): @@ -438,7 +438,7 @@ def test_create_dataset( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.create_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -459,19 +459,19 @@ def test_create_dataset_from_dict(): @pytest.mark.asyncio -async def test_create_dataset_async( - transport: str = "grpc_asyncio", request_type=service.CreateDatasetRequest -): +async def test_create_dataset_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.CreateDatasetRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.create_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -483,17 +483,12 @@ async def test_create_dataset_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.CreateDatasetRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_create_dataset_async_from_dict(): - await test_create_dataset_async(request_type=dict) - - def test_create_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -503,7 +498,7 @@ def test_create_dataset_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.create_dataset), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.create_dataset(request) @@ -528,7 +523,9 @@ async def test_create_dataset_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.create_dataset), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -549,7 +546,7 @@ def test_create_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.create_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -600,7 +597,9 @@ async def test_create_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.create_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -660,7 +659,7 @@ def test_get_dataset(transport: str = "grpc", request_type=service.GetDatasetReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.get_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = dataset.Dataset( name="name_value", @@ -682,7 +681,6 @@ def test_get_dataset(transport: str = "grpc", request_type=service.GetDatasetReq assert args[0] == service.GetDatasetRequest() # Establish that the response is the type that we expect. - assert isinstance(response, dataset.Dataset) assert response.name == "name_value" @@ -701,19 +699,19 @@ def test_get_dataset_from_dict(): @pytest.mark.asyncio -async def test_get_dataset_async( - transport: str = "grpc_asyncio", request_type=service.GetDatasetRequest -): +async def test_get_dataset_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.GetDatasetRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( dataset.Dataset( @@ -731,7 +729,7 @@ async def test_get_dataset_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.GetDatasetRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, dataset.Dataset) @@ -747,11 +745,6 @@ async def test_get_dataset_async( assert response.etag == "etag_value" -@pytest.mark.asyncio -async def test_get_dataset_async_from_dict(): - await test_get_dataset_async(request_type=dict) - - def test_get_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -761,7 +754,7 @@ def test_get_dataset_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.get_dataset), "__call__") as call: call.return_value = dataset.Dataset() client.get_dataset(request) @@ -786,7 +779,9 @@ async def test_get_dataset_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_dataset), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(dataset.Dataset()) await client.get_dataset(request) @@ -805,7 +800,7 @@ def test_get_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.get_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = dataset.Dataset() @@ -837,7 +832,9 @@ async def test_get_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = dataset.Dataset() @@ -878,7 +875,7 @@ def test_list_datasets( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListDatasetsResponse( next_page_token="next_page_token_value", @@ -893,7 +890,6 @@ def test_list_datasets( assert args[0] == service.ListDatasetsRequest() # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDatasetsPager) assert response.next_page_token == "next_page_token_value" @@ -904,19 +900,19 @@ def test_list_datasets_from_dict(): @pytest.mark.asyncio -async def test_list_datasets_async( - transport: str = "grpc_asyncio", request_type=service.ListDatasetsRequest -): +async def test_list_datasets_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ListDatasetsRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_datasets), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListDatasetsResponse(next_page_token="next_page_token_value",) @@ -928,7 +924,7 @@ async def test_list_datasets_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ListDatasetsRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListDatasetsAsyncPager) @@ -936,11 +932,6 @@ async def test_list_datasets_async( assert response.next_page_token == "next_page_token_value" -@pytest.mark.asyncio -async def test_list_datasets_async_from_dict(): - await test_list_datasets_async(request_type=dict) - - def test_list_datasets_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -950,7 +941,7 @@ def test_list_datasets_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: call.return_value = service.ListDatasetsResponse() client.list_datasets(request) @@ -975,7 +966,9 @@ async def test_list_datasets_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_datasets), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListDatasetsResponse() ) @@ -996,7 +989,7 @@ def test_list_datasets_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListDatasetsResponse() @@ -1028,7 +1021,9 @@ async def test_list_datasets_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_datasets), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListDatasetsResponse() @@ -1063,7 +1058,7 @@ def test_list_datasets_pager(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListDatasetsResponse( @@ -1097,7 +1092,7 @@ def test_list_datasets_pages(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListDatasetsResponse( @@ -1124,7 +1119,9 @@ async def test_list_datasets_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_datasets), "__call__", new_callable=mock.AsyncMock + type(client._client._transport.list_datasets), + "__call__", + new_callable=mock.AsyncMock, ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -1157,7 +1154,9 @@ async def test_list_datasets_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_datasets), "__call__", new_callable=mock.AsyncMock + type(client._client._transport.list_datasets), + "__call__", + new_callable=mock.AsyncMock, ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -1193,7 +1192,7 @@ def test_update_dataset( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.update_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset( name="name_value", @@ -1215,7 +1214,6 @@ def test_update_dataset( assert args[0] == service.UpdateDatasetRequest() # Establish that the response is the type that we expect. - assert isinstance(response, gca_dataset.Dataset) assert response.name == "name_value" @@ -1234,19 +1232,19 @@ def test_update_dataset_from_dict(): @pytest.mark.asyncio -async def test_update_dataset_async( - transport: str = "grpc_asyncio", request_type=service.UpdateDatasetRequest -): +async def test_update_dataset_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.UpdateDatasetRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.update_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( gca_dataset.Dataset( @@ -1264,7 +1262,7 @@ async def test_update_dataset_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.UpdateDatasetRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, gca_dataset.Dataset) @@ -1280,11 +1278,6 @@ async def test_update_dataset_async( assert response.etag == "etag_value" -@pytest.mark.asyncio -async def test_update_dataset_async_from_dict(): - await test_update_dataset_async(request_type=dict) - - def test_update_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1294,7 +1287,7 @@ def test_update_dataset_field_headers(): request.dataset.name = "dataset.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.update_dataset), "__call__") as call: call.return_value = gca_dataset.Dataset() client.update_dataset(request) @@ -1321,7 +1314,9 @@ async def test_update_dataset_field_headers_async(): request.dataset.name = "dataset.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.update_dataset), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gca_dataset.Dataset()) await client.update_dataset(request) @@ -1342,7 +1337,7 @@ def test_update_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.update_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset() @@ -1393,7 +1388,9 @@ async def test_update_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.update_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset() @@ -1453,7 +1450,7 @@ def test_delete_dataset( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.delete_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -1474,19 +1471,19 @@ def test_delete_dataset_from_dict(): @pytest.mark.asyncio -async def test_delete_dataset_async( - transport: str = "grpc_asyncio", request_type=service.DeleteDatasetRequest -): +async def test_delete_dataset_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.DeleteDatasetRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.delete_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -1498,17 +1495,12 @@ async def test_delete_dataset_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.DeleteDatasetRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_delete_dataset_async_from_dict(): - await test_delete_dataset_async(request_type=dict) - - def test_delete_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1518,7 +1510,7 @@ def test_delete_dataset_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.delete_dataset), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.delete_dataset(request) @@ -1543,7 +1535,9 @@ async def test_delete_dataset_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.delete_dataset), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -1564,7 +1558,7 @@ def test_delete_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.delete_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1596,7 +1590,9 @@ async def test_delete_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.delete_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1637,7 +1633,7 @@ def test_import_data(transport: str = "grpc", request_type=service.ImportDataReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.import_data), "__call__") as call: + with mock.patch.object(type(client._transport.import_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -1658,19 +1654,19 @@ def test_import_data_from_dict(): @pytest.mark.asyncio -async def test_import_data_async( - transport: str = "grpc_asyncio", request_type=service.ImportDataRequest -): +async def test_import_data_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ImportDataRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.import_data), "__call__") as call: + with mock.patch.object( + type(client._client._transport.import_data), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -1682,17 +1678,12 @@ async def test_import_data_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ImportDataRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_import_data_async_from_dict(): - await test_import_data_async(request_type=dict) - - def test_import_data_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1702,7 +1693,7 @@ def test_import_data_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.import_data), "__call__") as call: + with mock.patch.object(type(client._transport.import_data), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.import_data(request) @@ -1727,7 +1718,9 @@ async def test_import_data_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.import_data), "__call__") as call: + with mock.patch.object( + type(client._client._transport.import_data), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -1748,7 +1741,7 @@ def test_import_data_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.import_data), "__call__") as call: + with mock.patch.object(type(client._transport.import_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1793,7 +1786,9 @@ async def test_import_data_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.import_data), "__call__") as call: + with mock.patch.object( + type(client._client._transport.import_data), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1847,7 +1842,7 @@ def test_export_data(transport: str = "grpc", request_type=service.ExportDataReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_data), "__call__") as call: + with mock.patch.object(type(client._transport.export_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -1868,19 +1863,19 @@ def test_export_data_from_dict(): @pytest.mark.asyncio -async def test_export_data_async( - transport: str = "grpc_asyncio", request_type=service.ExportDataRequest -): +async def test_export_data_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ExportDataRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_data), "__call__") as call: + with mock.patch.object( + type(client._client._transport.export_data), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -1892,17 +1887,12 @@ async def test_export_data_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ExportDataRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_export_data_async_from_dict(): - await test_export_data_async(request_type=dict) - - def test_export_data_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1912,7 +1902,7 @@ def test_export_data_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_data), "__call__") as call: + with mock.patch.object(type(client._transport.export_data), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.export_data(request) @@ -1937,7 +1927,9 @@ async def test_export_data_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_data), "__call__") as call: + with mock.patch.object( + type(client._client._transport.export_data), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -1958,7 +1950,7 @@ def test_export_data_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_data), "__call__") as call: + with mock.patch.object(type(client._transport.export_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -2009,7 +2001,9 @@ async def test_export_data_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_data), "__call__") as call: + with mock.patch.object( + type(client._client._transport.export_data), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -2072,7 +2066,7 @@ def test_get_annotation_spec( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_annotation_spec), "__call__" + type(client._transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = annotation_spec.AnnotationSpec( @@ -2088,7 +2082,6 @@ def test_get_annotation_spec( assert args[0] == service.GetAnnotationSpecRequest() # Establish that the response is the type that we expect. - assert isinstance(response, annotation_spec.AnnotationSpec) assert response.name == "name_value" @@ -2103,20 +2096,18 @@ def test_get_annotation_spec_from_dict(): @pytest.mark.asyncio -async def test_get_annotation_spec_async( - transport: str = "grpc_asyncio", request_type=service.GetAnnotationSpecRequest -): +async def test_get_annotation_spec_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.GetAnnotationSpecRequest() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_annotation_spec), "__call__" + type(client._client._transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -2133,7 +2124,7 @@ async def test_get_annotation_spec_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.GetAnnotationSpecRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, annotation_spec.AnnotationSpec) @@ -2145,11 +2136,6 @@ async def test_get_annotation_spec_async( assert response.example_count == 1396 -@pytest.mark.asyncio -async def test_get_annotation_spec_async_from_dict(): - await test_get_annotation_spec_async(request_type=dict) - - def test_get_annotation_spec_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2160,7 +2146,7 @@ def test_get_annotation_spec_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_annotation_spec), "__call__" + type(client._transport.get_annotation_spec), "__call__" ) as call: call.return_value = annotation_spec.AnnotationSpec() @@ -2187,7 +2173,7 @@ async def test_get_annotation_spec_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_annotation_spec), "__call__" + type(client._client._transport.get_annotation_spec), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( annotation_spec.AnnotationSpec() @@ -2210,7 +2196,7 @@ def test_get_annotation_spec_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_annotation_spec), "__call__" + type(client._transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = annotation_spec.AnnotationSpec() @@ -2244,7 +2230,7 @@ async def test_get_annotation_spec_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_annotation_spec), "__call__" + type(client._client._transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = annotation_spec.AnnotationSpec() @@ -2286,7 +2272,7 @@ def test_create_model(transport: str = "grpc", request_type=service.CreateModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_model), "__call__") as call: + with mock.patch.object(type(client._transport.create_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -2307,19 +2293,19 @@ def test_create_model_from_dict(): @pytest.mark.asyncio -async def test_create_model_async( - transport: str = "grpc_asyncio", request_type=service.CreateModelRequest -): +async def test_create_model_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.CreateModelRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.create_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -2331,17 +2317,12 @@ async def test_create_model_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.CreateModelRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_create_model_async_from_dict(): - await test_create_model_async(request_type=dict) - - def test_create_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2351,7 +2332,7 @@ def test_create_model_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_model), "__call__") as call: + with mock.patch.object(type(client._transport.create_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.create_model(request) @@ -2376,7 +2357,9 @@ async def test_create_model_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.create_model), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -2397,7 +2380,7 @@ def test_create_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_model), "__call__") as call: + with mock.patch.object(type(client._transport.create_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -2448,7 +2431,9 @@ async def test_create_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.create_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -2508,7 +2493,7 @@ def test_get_model(transport: str = "grpc", request_type=service.GetModelRequest request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_model), "__call__") as call: + with mock.patch.object(type(client._transport.get_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = model.Model( name="name_value", @@ -2530,7 +2515,6 @@ def test_get_model(transport: str = "grpc", request_type=service.GetModelRequest assert args[0] == service.GetModelRequest() # Establish that the response is the type that we expect. - assert isinstance(response, model.Model) assert response.name == "name_value" @@ -2549,19 +2533,19 @@ def test_get_model_from_dict(): @pytest.mark.asyncio -async def test_get_model_async( - transport: str = "grpc_asyncio", request_type=service.GetModelRequest -): +async def test_get_model_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.GetModelRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( model.Model( @@ -2579,7 +2563,7 @@ async def test_get_model_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.GetModelRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, model.Model) @@ -2595,11 +2579,6 @@ async def test_get_model_async( assert response.etag == "etag_value" -@pytest.mark.asyncio -async def test_get_model_async_from_dict(): - await test_get_model_async(request_type=dict) - - def test_get_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2609,7 +2588,7 @@ def test_get_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_model), "__call__") as call: + with mock.patch.object(type(client._transport.get_model), "__call__") as call: call.return_value = model.Model() client.get_model(request) @@ -2634,7 +2613,9 @@ async def test_get_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_model), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) await client.get_model(request) @@ -2653,7 +2634,7 @@ def test_get_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_model), "__call__") as call: + with mock.patch.object(type(client._transport.get_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = model.Model() @@ -2685,7 +2666,9 @@ async def test_get_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = model.Model() @@ -2724,7 +2707,7 @@ def test_list_models(transport: str = "grpc", request_type=service.ListModelsReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object(type(client._transport.list_models), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelsResponse( next_page_token="next_page_token_value", @@ -2739,7 +2722,6 @@ def test_list_models(transport: str = "grpc", request_type=service.ListModelsReq assert args[0] == service.ListModelsRequest() # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListModelsPager) assert response.next_page_token == "next_page_token_value" @@ -2750,19 +2732,19 @@ def test_list_models_from_dict(): @pytest.mark.asyncio -async def test_list_models_async( - transport: str = "grpc_asyncio", request_type=service.ListModelsRequest -): +async def test_list_models_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ListModelsRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_models), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListModelsResponse(next_page_token="next_page_token_value",) @@ -2774,7 +2756,7 @@ async def test_list_models_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ListModelsRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListModelsAsyncPager) @@ -2782,11 +2764,6 @@ async def test_list_models_async( assert response.next_page_token == "next_page_token_value" -@pytest.mark.asyncio -async def test_list_models_async_from_dict(): - await test_list_models_async(request_type=dict) - - def test_list_models_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2796,7 +2773,7 @@ def test_list_models_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object(type(client._transport.list_models), "__call__") as call: call.return_value = service.ListModelsResponse() client.list_models(request) @@ -2821,7 +2798,9 @@ async def test_list_models_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_models), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListModelsResponse() ) @@ -2842,7 +2821,7 @@ def test_list_models_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object(type(client._transport.list_models), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelsResponse() @@ -2874,7 +2853,9 @@ async def test_list_models_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_models), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelsResponse() @@ -2909,7 +2890,7 @@ def test_list_models_pager(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object(type(client._transport.list_models), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListModelsResponse( @@ -2939,7 +2920,7 @@ def test_list_models_pages(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object(type(client._transport.list_models), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListModelsResponse( @@ -2962,7 +2943,9 @@ async def test_list_models_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_models), "__call__", new_callable=mock.AsyncMock + type(client._client._transport.list_models), + "__call__", + new_callable=mock.AsyncMock, ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -2991,7 +2974,9 @@ async def test_list_models_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_models), "__call__", new_callable=mock.AsyncMock + type(client._client._transport.list_models), + "__call__", + new_callable=mock.AsyncMock, ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -3021,7 +3006,7 @@ def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + with mock.patch.object(type(client._transport.delete_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -3042,19 +3027,19 @@ def test_delete_model_from_dict(): @pytest.mark.asyncio -async def test_delete_model_async( - transport: str = "grpc_asyncio", request_type=service.DeleteModelRequest -): +async def test_delete_model_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.DeleteModelRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.delete_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -3066,17 +3051,12 @@ async def test_delete_model_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.DeleteModelRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_delete_model_async_from_dict(): - await test_delete_model_async(request_type=dict) - - def test_delete_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3086,7 +3066,7 @@ def test_delete_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + with mock.patch.object(type(client._transport.delete_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.delete_model(request) @@ -3111,7 +3091,9 @@ async def test_delete_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.delete_model), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -3132,7 +3114,7 @@ def test_delete_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + with mock.patch.object(type(client._transport.delete_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3164,7 +3146,9 @@ async def test_delete_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.delete_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3205,7 +3189,7 @@ def test_update_model(transport: str = "grpc", request_type=service.UpdateModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_model), "__call__") as call: + with mock.patch.object(type(client._transport.update_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_model.Model( name="name_value", @@ -3227,7 +3211,6 @@ def test_update_model(transport: str = "grpc", request_type=service.UpdateModelR assert args[0] == service.UpdateModelRequest() # Establish that the response is the type that we expect. - assert isinstance(response, gca_model.Model) assert response.name == "name_value" @@ -3246,19 +3229,19 @@ def test_update_model_from_dict(): @pytest.mark.asyncio -async def test_update_model_async( - transport: str = "grpc_asyncio", request_type=service.UpdateModelRequest -): +async def test_update_model_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.UpdateModelRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.update_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( gca_model.Model( @@ -3276,7 +3259,7 @@ async def test_update_model_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.UpdateModelRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, gca_model.Model) @@ -3292,11 +3275,6 @@ async def test_update_model_async( assert response.etag == "etag_value" -@pytest.mark.asyncio -async def test_update_model_async_from_dict(): - await test_update_model_async(request_type=dict) - - def test_update_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3306,7 +3284,7 @@ def test_update_model_field_headers(): request.model.name = "model.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_model), "__call__") as call: + with mock.patch.object(type(client._transport.update_model), "__call__") as call: call.return_value = gca_model.Model() client.update_model(request) @@ -3331,7 +3309,9 @@ async def test_update_model_field_headers_async(): request.model.name = "model.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.update_model), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gca_model.Model()) await client.update_model(request) @@ -3350,7 +3330,7 @@ def test_update_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_model), "__call__") as call: + with mock.patch.object(type(client._transport.update_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_model.Model() @@ -3401,7 +3381,9 @@ async def test_update_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.update_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = gca_model.Model() @@ -3459,7 +3441,7 @@ def test_deploy_model(transport: str = "grpc", request_type=service.DeployModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: + with mock.patch.object(type(client._transport.deploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -3480,19 +3462,19 @@ def test_deploy_model_from_dict(): @pytest.mark.asyncio -async def test_deploy_model_async( - transport: str = "grpc_asyncio", request_type=service.DeployModelRequest -): +async def test_deploy_model_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.DeployModelRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.deploy_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -3504,17 +3486,12 @@ async def test_deploy_model_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.DeployModelRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_deploy_model_async_from_dict(): - await test_deploy_model_async(request_type=dict) - - def test_deploy_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3524,7 +3501,7 @@ def test_deploy_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: + with mock.patch.object(type(client._transport.deploy_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.deploy_model(request) @@ -3549,7 +3526,9 @@ async def test_deploy_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.deploy_model), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -3570,7 +3549,7 @@ def test_deploy_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: + with mock.patch.object(type(client._transport.deploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3602,7 +3581,9 @@ async def test_deploy_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.deploy_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3645,7 +3626,7 @@ def test_undeploy_model( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: + with mock.patch.object(type(client._transport.undeploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -3666,19 +3647,19 @@ def test_undeploy_model_from_dict(): @pytest.mark.asyncio -async def test_undeploy_model_async( - transport: str = "grpc_asyncio", request_type=service.UndeployModelRequest -): +async def test_undeploy_model_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.UndeployModelRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.undeploy_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -3690,17 +3671,12 @@ async def test_undeploy_model_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.UndeployModelRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_undeploy_model_async_from_dict(): - await test_undeploy_model_async(request_type=dict) - - def test_undeploy_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3710,7 +3686,7 @@ def test_undeploy_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: + with mock.patch.object(type(client._transport.undeploy_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.undeploy_model(request) @@ -3735,7 +3711,9 @@ async def test_undeploy_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.undeploy_model), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -3756,7 +3734,7 @@ def test_undeploy_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: + with mock.patch.object(type(client._transport.undeploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3788,7 +3766,9 @@ async def test_undeploy_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.undeploy_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3829,7 +3809,7 @@ def test_export_model(transport: str = "grpc", request_type=service.ExportModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_model), "__call__") as call: + with mock.patch.object(type(client._transport.export_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -3850,19 +3830,19 @@ def test_export_model_from_dict(): @pytest.mark.asyncio -async def test_export_model_async( - transport: str = "grpc_asyncio", request_type=service.ExportModelRequest -): +async def test_export_model_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ExportModelRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.export_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -3874,17 +3854,12 @@ async def test_export_model_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ExportModelRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_export_model_async_from_dict(): - await test_export_model_async(request_type=dict) - - def test_export_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3894,7 +3869,7 @@ def test_export_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_model), "__call__") as call: + with mock.patch.object(type(client._transport.export_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.export_model(request) @@ -3919,7 +3894,9 @@ async def test_export_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.export_model), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -3940,7 +3917,7 @@ def test_export_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_model), "__call__") as call: + with mock.patch.object(type(client._transport.export_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -3991,7 +3968,9 @@ async def test_export_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.export_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -4054,7 +4033,7 @@ def test_get_model_evaluation( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_model_evaluation), "__call__" + type(client._transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = model_evaluation.ModelEvaluation( @@ -4076,7 +4055,6 @@ def test_get_model_evaluation( assert args[0] == service.GetModelEvaluationRequest() # Establish that the response is the type that we expect. - assert isinstance(response, model_evaluation.ModelEvaluation) assert response.name == "name_value" @@ -4093,20 +4071,18 @@ def test_get_model_evaluation_from_dict(): @pytest.mark.asyncio -async def test_get_model_evaluation_async( - transport: str = "grpc_asyncio", request_type=service.GetModelEvaluationRequest -): +async def test_get_model_evaluation_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.GetModelEvaluationRequest() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_model_evaluation), "__call__" + type(client._client._transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -4124,7 +4100,7 @@ async def test_get_model_evaluation_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.GetModelEvaluationRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, model_evaluation.ModelEvaluation) @@ -4138,11 +4114,6 @@ async def test_get_model_evaluation_async( assert response.evaluated_example_count == 2446 -@pytest.mark.asyncio -async def test_get_model_evaluation_async_from_dict(): - await test_get_model_evaluation_async(request_type=dict) - - def test_get_model_evaluation_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4153,7 +4124,7 @@ def test_get_model_evaluation_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_model_evaluation), "__call__" + type(client._transport.get_model_evaluation), "__call__" ) as call: call.return_value = model_evaluation.ModelEvaluation() @@ -4180,7 +4151,7 @@ async def test_get_model_evaluation_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_model_evaluation), "__call__" + type(client._client._transport.get_model_evaluation), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( model_evaluation.ModelEvaluation() @@ -4203,7 +4174,7 @@ def test_get_model_evaluation_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_model_evaluation), "__call__" + type(client._transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = model_evaluation.ModelEvaluation() @@ -4237,7 +4208,7 @@ async def test_get_model_evaluation_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_model_evaluation), "__call__" + type(client._client._transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = model_evaluation.ModelEvaluation() @@ -4282,7 +4253,7 @@ def test_list_model_evaluations( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelEvaluationsResponse( @@ -4298,7 +4269,6 @@ def test_list_model_evaluations( assert args[0] == service.ListModelEvaluationsRequest() # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListModelEvaluationsPager) assert response.next_page_token == "next_page_token_value" @@ -4309,20 +4279,18 @@ def test_list_model_evaluations_from_dict(): @pytest.mark.asyncio -async def test_list_model_evaluations_async( - transport: str = "grpc_asyncio", request_type=service.ListModelEvaluationsRequest -): +async def test_list_model_evaluations_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ListModelEvaluationsRequest() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._client._transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -4337,7 +4305,7 @@ async def test_list_model_evaluations_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ListModelEvaluationsRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListModelEvaluationsAsyncPager) @@ -4345,11 +4313,6 @@ async def test_list_model_evaluations_async( assert response.next_page_token == "next_page_token_value" -@pytest.mark.asyncio -async def test_list_model_evaluations_async_from_dict(): - await test_list_model_evaluations_async(request_type=dict) - - def test_list_model_evaluations_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4360,7 +4323,7 @@ def test_list_model_evaluations_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._transport.list_model_evaluations), "__call__" ) as call: call.return_value = service.ListModelEvaluationsResponse() @@ -4387,7 +4350,7 @@ async def test_list_model_evaluations_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._client._transport.list_model_evaluations), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListModelEvaluationsResponse() @@ -4410,7 +4373,7 @@ def test_list_model_evaluations_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelEvaluationsResponse() @@ -4450,7 +4413,7 @@ async def test_list_model_evaluations_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._client._transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelEvaluationsResponse() @@ -4493,7 +4456,7 @@ def test_list_model_evaluations_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._transport.list_model_evaluations), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -4539,7 +4502,7 @@ def test_list_model_evaluations_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._transport.list_model_evaluations), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -4577,7 +4540,7 @@ async def test_list_model_evaluations_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), + type(client._client._transport.list_model_evaluations), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -4622,7 +4585,7 @@ async def test_list_model_evaluations_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), + type(client._client._transport.list_model_evaluations), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -4694,7 +4657,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = AutoMlClient(transport=transport) - assert client.transport is transport + assert client._transport is transport def test_transport_get_channel(): @@ -4727,7 +4690,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client.transport, transports.AutoMlGrpcTransport,) + assert isinstance(client._transport, transports.AutoMlGrpcTransport,) def test_auto_ml_base_transport_error(): @@ -4843,7 +4806,7 @@ def test_auto_ml_host_no_port(): api_endpoint="automl.googleapis.com" ), ) - assert client.transport._host == "automl.googleapis.com:443" + assert client._transport._host == "automl.googleapis.com:443" def test_auto_ml_host_with_port(): @@ -4853,7 +4816,7 @@ def test_auto_ml_host_with_port(): api_endpoint="automl.googleapis.com:8000" ), ) - assert client.transport._host == "automl.googleapis.com:8000" + assert client._transport._host == "automl.googleapis.com:8000" def test_auto_ml_grpc_transport_channel(): @@ -4961,7 +4924,7 @@ def test_auto_ml_grpc_lro_client(): client = AutoMlClient( credentials=credentials.AnonymousCredentials(), transport="grpc", ) - transport = client.transport + transport = client._transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsClient,) @@ -4974,7 +4937,7 @@ def test_auto_ml_grpc_lro_async_client(): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", ) - transport = client.transport + transport = client._client._transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,) @@ -4983,42 +4946,10 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_annotation_spec_path(): +def test_dataset_path(): project = "squid" location = "clam" dataset = "whelk" - annotation_spec = "octopus" - - expected = "projects/{project}/locations/{location}/datasets/{dataset}/annotationSpecs/{annotation_spec}".format( - project=project, - location=location, - dataset=dataset, - annotation_spec=annotation_spec, - ) - actual = AutoMlClient.annotation_spec_path( - project, location, dataset, annotation_spec - ) - assert expected == actual - - -def test_parse_annotation_spec_path(): - expected = { - "project": "oyster", - "location": "nudibranch", - "dataset": "cuttlefish", - "annotation_spec": "mussel", - } - path = AutoMlClient.annotation_spec_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_annotation_spec_path(path) - assert expected == actual - - -def test_dataset_path(): - project = "winkle" - location = "nautilus" - dataset = "scallop" expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( project=project, location=location, dataset=dataset, @@ -5029,9 +4960,9 @@ def test_dataset_path(): def test_parse_dataset_path(): expected = { - "project": "abalone", - "location": "squid", - "dataset": "clam", + "project": "octopus", + "location": "oyster", + "dataset": "nudibranch", } path = AutoMlClient.dataset_path(**expected) @@ -5041,9 +4972,9 @@ def test_parse_dataset_path(): def test_model_path(): - project = "whelk" - location = "octopus" - model = "oyster" + project = "squid" + location = "clam" + model = "whelk" expected = "projects/{project}/locations/{location}/models/{model}".format( project=project, location=location, model=model, @@ -5054,9 +4985,9 @@ def test_model_path(): def test_parse_model_path(): expected = { - "project": "nudibranch", - "location": "cuttlefish", - "model": "mussel", + "project": "octopus", + "location": "oyster", + "model": "nudibranch", } path = AutoMlClient.model_path(**expected) @@ -5065,139 +4996,6 @@ def test_parse_model_path(): assert expected == actual -def test_model_evaluation_path(): - project = "winkle" - location = "nautilus" - model = "scallop" - model_evaluation = "abalone" - - expected = "projects/{project}/locations/{location}/models/{model}/modelEvaluations/{model_evaluation}".format( - project=project, - location=location, - model=model, - model_evaluation=model_evaluation, - ) - actual = AutoMlClient.model_evaluation_path( - project, location, model, model_evaluation - ) - assert expected == actual - - -def test_parse_model_evaluation_path(): - expected = { - "project": "squid", - "location": "clam", - "model": "whelk", - "model_evaluation": "octopus", - } - path = AutoMlClient.model_evaluation_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_model_evaluation_path(path) - assert expected == actual - - -def test_common_billing_account_path(): - billing_account = "oyster" - - expected = "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - actual = AutoMlClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "nudibranch", - } - path = AutoMlClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_common_billing_account_path(path) - assert expected == actual - - -def test_common_folder_path(): - folder = "cuttlefish" - - expected = "folders/{folder}".format(folder=folder,) - actual = AutoMlClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "mussel", - } - path = AutoMlClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_common_folder_path(path) - assert expected == actual - - -def test_common_organization_path(): - organization = "winkle" - - expected = "organizations/{organization}".format(organization=organization,) - actual = AutoMlClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "nautilus", - } - path = AutoMlClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_common_organization_path(path) - assert expected == actual - - -def test_common_project_path(): - project = "scallop" - - expected = "projects/{project}".format(project=project,) - actual = AutoMlClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "abalone", - } - path = AutoMlClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_common_project_path(path) - assert expected == actual - - -def test_common_location_path(): - project = "squid" - location = "clam" - - expected = "projects/{project}/locations/{location}".format( - project=project, location=location, - ) - actual = AutoMlClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "whelk", - "location": "octopus", - } - path = AutoMlClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_common_location_path(path) - assert expected == actual - - def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() diff --git a/tests/unit/gapic/automl_v1/test_prediction_service.py b/tests/unit/gapic/automl_v1/test_prediction_service.py index 6fba03de..fd886203 100644 --- a/tests/unit/gapic/automl_v1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1/test_prediction_service.py @@ -106,12 +106,12 @@ def test_prediction_service_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client.transport._credentials == creds + assert client._transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client.transport._credentials == creds + assert client._transport._credentials == creds - assert client.transport._host == "automl.googleapis.com:443" + assert client._transport._host == "automl.googleapis.com:443" def test_prediction_service_client_get_transport_class(): @@ -471,7 +471,7 @@ def test_predict( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.predict), "__call__") as call: + with mock.patch.object(type(client._transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = prediction_service.PredictResponse() @@ -484,7 +484,6 @@ def test_predict( assert args[0] == prediction_service.PredictRequest() # Establish that the response is the type that we expect. - assert isinstance(response, prediction_service.PredictResponse) @@ -493,19 +492,17 @@ def test_predict_from_dict(): @pytest.mark.asyncio -async def test_predict_async( - transport: str = "grpc_asyncio", request_type=prediction_service.PredictRequest -): +async def test_predict_async(transport: str = "grpc_asyncio"): client = PredictionServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = prediction_service.PredictRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.predict), "__call__") as call: + with mock.patch.object(type(client._client._transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( prediction_service.PredictResponse() @@ -517,17 +514,12 @@ async def test_predict_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == prediction_service.PredictRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, prediction_service.PredictResponse) -@pytest.mark.asyncio -async def test_predict_async_from_dict(): - await test_predict_async(request_type=dict) - - def test_predict_field_headers(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -537,7 +529,7 @@ def test_predict_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.predict), "__call__") as call: + with mock.patch.object(type(client._transport.predict), "__call__") as call: call.return_value = prediction_service.PredictResponse() client.predict(request) @@ -564,7 +556,7 @@ async def test_predict_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.predict), "__call__") as call: + with mock.patch.object(type(client._client._transport.predict), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( prediction_service.PredictResponse() ) @@ -585,7 +577,7 @@ def test_predict_flattened(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.predict), "__call__") as call: + with mock.patch.object(type(client._transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = prediction_service.PredictResponse() @@ -636,7 +628,7 @@ async def test_predict_flattened_async(): ) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.predict), "__call__") as call: + with mock.patch.object(type(client._client._transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = prediction_service.PredictResponse() @@ -698,7 +690,7 @@ def test_batch_predict( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: + with mock.patch.object(type(client._transport.batch_predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -719,19 +711,19 @@ def test_batch_predict_from_dict(): @pytest.mark.asyncio -async def test_batch_predict_async( - transport: str = "grpc_asyncio", request_type=prediction_service.BatchPredictRequest -): +async def test_batch_predict_async(transport: str = "grpc_asyncio"): client = PredictionServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = prediction_service.BatchPredictRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: + with mock.patch.object( + type(client._client._transport.batch_predict), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -743,17 +735,12 @@ async def test_batch_predict_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == prediction_service.BatchPredictRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_batch_predict_async_from_dict(): - await test_batch_predict_async(request_type=dict) - - def test_batch_predict_field_headers(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -763,7 +750,7 @@ def test_batch_predict_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: + with mock.patch.object(type(client._transport.batch_predict), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.batch_predict(request) @@ -790,7 +777,9 @@ async def test_batch_predict_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: + with mock.patch.object( + type(client._client._transport.batch_predict), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -811,7 +800,7 @@ def test_batch_predict_flattened(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: + with mock.patch.object(type(client._transport.batch_predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -878,7 +867,9 @@ async def test_batch_predict_flattened_async(): ) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: + with mock.patch.object( + type(client._client._transport.batch_predict), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -980,7 +971,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = PredictionServiceClient(transport=transport) - assert client.transport is transport + assert client._transport is transport def test_transport_get_channel(): @@ -1016,7 +1007,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client.transport, transports.PredictionServiceGrpcTransport,) + assert isinstance(client._transport, transports.PredictionServiceGrpcTransport,) def test_prediction_service_base_transport_error(): @@ -1116,7 +1107,7 @@ def test_prediction_service_host_no_port(): api_endpoint="automl.googleapis.com" ), ) - assert client.transport._host == "automl.googleapis.com:443" + assert client._transport._host == "automl.googleapis.com:443" def test_prediction_service_host_with_port(): @@ -1126,7 +1117,7 @@ def test_prediction_service_host_with_port(): api_endpoint="automl.googleapis.com:8000" ), ) - assert client.transport._host == "automl.googleapis.com:8000" + assert client._transport._host == "automl.googleapis.com:8000" def test_prediction_service_grpc_transport_channel(): @@ -1242,7 +1233,7 @@ def test_prediction_service_grpc_lro_client(): client = PredictionServiceClient( credentials=credentials.AnonymousCredentials(), transport="grpc", ) - transport = client.transport + transport = client._transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsClient,) @@ -1255,7 +1246,7 @@ def test_prediction_service_grpc_lro_async_client(): client = PredictionServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", ) - transport = client.transport + transport = client._client._transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,) @@ -1264,132 +1255,6 @@ def test_prediction_service_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_model_path(): - project = "squid" - location = "clam" - model = "whelk" - - expected = "projects/{project}/locations/{location}/models/{model}".format( - project=project, location=location, model=model, - ) - actual = PredictionServiceClient.model_path(project, location, model) - assert expected == actual - - -def test_parse_model_path(): - expected = { - "project": "octopus", - "location": "oyster", - "model": "nudibranch", - } - path = PredictionServiceClient.model_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_model_path(path) - assert expected == actual - - -def test_common_billing_account_path(): - billing_account = "cuttlefish" - - expected = "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - actual = PredictionServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "mussel", - } - path = PredictionServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_billing_account_path(path) - assert expected == actual - - -def test_common_folder_path(): - folder = "winkle" - - expected = "folders/{folder}".format(folder=folder,) - actual = PredictionServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "nautilus", - } - path = PredictionServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_folder_path(path) - assert expected == actual - - -def test_common_organization_path(): - organization = "scallop" - - expected = "organizations/{organization}".format(organization=organization,) - actual = PredictionServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "abalone", - } - path = PredictionServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_organization_path(path) - assert expected == actual - - -def test_common_project_path(): - project = "squid" - - expected = "projects/{project}".format(project=project,) - actual = PredictionServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "clam", - } - path = PredictionServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_project_path(path) - assert expected == actual - - -def test_common_location_path(): - project = "whelk" - location = "octopus" - - expected = "projects/{project}/locations/{location}".format( - project=project, location=location, - ) - actual = PredictionServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "oyster", - "location": "nudibranch", - } - path = PredictionServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_location_path(path) - assert expected == actual - - def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() diff --git a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py index 1cfdb65b..09cb0749 100644 --- a/tests/unit/gapic/automl_v1beta1/test_auto_ml.py +++ b/tests/unit/gapic/automl_v1beta1/test_auto_ml.py @@ -44,6 +44,7 @@ from google.cloud.automl_v1beta1.types import column_spec from google.cloud.automl_v1beta1.types import column_spec as gca_column_spec from google.cloud.automl_v1beta1.types import data_stats +from google.cloud.automl_v1beta1.types import data_stats as gca_data_stats from google.cloud.automl_v1beta1.types import data_types from google.cloud.automl_v1beta1.types import dataset from google.cloud.automl_v1beta1.types import dataset as gca_dataset @@ -116,12 +117,12 @@ def test_auto_ml_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client.transport._credentials == creds + assert client._transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client.transport._credentials == creds + assert client._transport._credentials == creds - assert client.transport._host == "automl.googleapis.com:443" + assert client._transport._host == "automl.googleapis.com:443" def test_auto_ml_client_get_transport_class(): @@ -447,7 +448,7 @@ def test_create_dataset( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.create_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset( name="name_value", @@ -469,7 +470,6 @@ def test_create_dataset( assert args[0] == service.CreateDatasetRequest() # Establish that the response is the type that we expect. - assert isinstance(response, gca_dataset.Dataset) assert response.name == "name_value" @@ -488,19 +488,19 @@ def test_create_dataset_from_dict(): @pytest.mark.asyncio -async def test_create_dataset_async( - transport: str = "grpc_asyncio", request_type=service.CreateDatasetRequest -): +async def test_create_dataset_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.CreateDatasetRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.create_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( gca_dataset.Dataset( @@ -518,7 +518,7 @@ async def test_create_dataset_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.CreateDatasetRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, gca_dataset.Dataset) @@ -534,11 +534,6 @@ async def test_create_dataset_async( assert response.etag == "etag_value" -@pytest.mark.asyncio -async def test_create_dataset_async_from_dict(): - await test_create_dataset_async(request_type=dict) - - def test_create_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -548,7 +543,7 @@ def test_create_dataset_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.create_dataset), "__call__") as call: call.return_value = gca_dataset.Dataset() client.create_dataset(request) @@ -573,7 +568,9 @@ async def test_create_dataset_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.create_dataset), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gca_dataset.Dataset()) await client.create_dataset(request) @@ -592,7 +589,7 @@ def test_create_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.create_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset() @@ -643,7 +640,9 @@ async def test_create_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.create_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset() @@ -701,7 +700,7 @@ def test_get_dataset(transport: str = "grpc", request_type=service.GetDatasetReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.get_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = dataset.Dataset( name="name_value", @@ -723,7 +722,6 @@ def test_get_dataset(transport: str = "grpc", request_type=service.GetDatasetReq assert args[0] == service.GetDatasetRequest() # Establish that the response is the type that we expect. - assert isinstance(response, dataset.Dataset) assert response.name == "name_value" @@ -742,19 +740,19 @@ def test_get_dataset_from_dict(): @pytest.mark.asyncio -async def test_get_dataset_async( - transport: str = "grpc_asyncio", request_type=service.GetDatasetRequest -): +async def test_get_dataset_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.GetDatasetRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( dataset.Dataset( @@ -772,7 +770,7 @@ async def test_get_dataset_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.GetDatasetRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, dataset.Dataset) @@ -788,11 +786,6 @@ async def test_get_dataset_async( assert response.etag == "etag_value" -@pytest.mark.asyncio -async def test_get_dataset_async_from_dict(): - await test_get_dataset_async(request_type=dict) - - def test_get_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -802,7 +795,7 @@ def test_get_dataset_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.get_dataset), "__call__") as call: call.return_value = dataset.Dataset() client.get_dataset(request) @@ -827,7 +820,9 @@ async def test_get_dataset_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_dataset), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(dataset.Dataset()) await client.get_dataset(request) @@ -846,7 +841,7 @@ def test_get_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.get_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = dataset.Dataset() @@ -878,7 +873,9 @@ async def test_get_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = dataset.Dataset() @@ -919,7 +916,7 @@ def test_list_datasets( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListDatasetsResponse( next_page_token="next_page_token_value", @@ -934,7 +931,6 @@ def test_list_datasets( assert args[0] == service.ListDatasetsRequest() # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDatasetsPager) assert response.next_page_token == "next_page_token_value" @@ -945,19 +941,19 @@ def test_list_datasets_from_dict(): @pytest.mark.asyncio -async def test_list_datasets_async( - transport: str = "grpc_asyncio", request_type=service.ListDatasetsRequest -): +async def test_list_datasets_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ListDatasetsRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_datasets), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListDatasetsResponse(next_page_token="next_page_token_value",) @@ -969,7 +965,7 @@ async def test_list_datasets_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ListDatasetsRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListDatasetsAsyncPager) @@ -977,11 +973,6 @@ async def test_list_datasets_async( assert response.next_page_token == "next_page_token_value" -@pytest.mark.asyncio -async def test_list_datasets_async_from_dict(): - await test_list_datasets_async(request_type=dict) - - def test_list_datasets_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -991,7 +982,7 @@ def test_list_datasets_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: call.return_value = service.ListDatasetsResponse() client.list_datasets(request) @@ -1016,7 +1007,9 @@ async def test_list_datasets_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_datasets), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListDatasetsResponse() ) @@ -1037,7 +1030,7 @@ def test_list_datasets_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListDatasetsResponse() @@ -1069,7 +1062,9 @@ async def test_list_datasets_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_datasets), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListDatasetsResponse() @@ -1104,7 +1099,7 @@ def test_list_datasets_pager(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListDatasetsResponse( @@ -1138,7 +1133,7 @@ def test_list_datasets_pages(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + with mock.patch.object(type(client._transport.list_datasets), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListDatasetsResponse( @@ -1165,7 +1160,9 @@ async def test_list_datasets_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_datasets), "__call__", new_callable=mock.AsyncMock + type(client._client._transport.list_datasets), + "__call__", + new_callable=mock.AsyncMock, ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -1198,7 +1195,9 @@ async def test_list_datasets_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_datasets), "__call__", new_callable=mock.AsyncMock + type(client._client._transport.list_datasets), + "__call__", + new_callable=mock.AsyncMock, ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -1234,7 +1233,7 @@ def test_update_dataset( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.update_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset( name="name_value", @@ -1256,7 +1255,6 @@ def test_update_dataset( assert args[0] == service.UpdateDatasetRequest() # Establish that the response is the type that we expect. - assert isinstance(response, gca_dataset.Dataset) assert response.name == "name_value" @@ -1275,19 +1273,19 @@ def test_update_dataset_from_dict(): @pytest.mark.asyncio -async def test_update_dataset_async( - transport: str = "grpc_asyncio", request_type=service.UpdateDatasetRequest -): +async def test_update_dataset_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.UpdateDatasetRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.update_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( gca_dataset.Dataset( @@ -1305,7 +1303,7 @@ async def test_update_dataset_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.UpdateDatasetRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, gca_dataset.Dataset) @@ -1321,11 +1319,6 @@ async def test_update_dataset_async( assert response.etag == "etag_value" -@pytest.mark.asyncio -async def test_update_dataset_async_from_dict(): - await test_update_dataset_async(request_type=dict) - - def test_update_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1335,7 +1328,7 @@ def test_update_dataset_field_headers(): request.dataset.name = "dataset.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.update_dataset), "__call__") as call: call.return_value = gca_dataset.Dataset() client.update_dataset(request) @@ -1362,7 +1355,9 @@ async def test_update_dataset_field_headers_async(): request.dataset.name = "dataset.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.update_dataset), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gca_dataset.Dataset()) await client.update_dataset(request) @@ -1383,7 +1378,7 @@ def test_update_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.update_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset() @@ -1430,7 +1425,9 @@ async def test_update_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.update_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = gca_dataset.Dataset() @@ -1486,7 +1483,7 @@ def test_delete_dataset( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.delete_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -1507,19 +1504,19 @@ def test_delete_dataset_from_dict(): @pytest.mark.asyncio -async def test_delete_dataset_async( - transport: str = "grpc_asyncio", request_type=service.DeleteDatasetRequest -): +async def test_delete_dataset_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.DeleteDatasetRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.delete_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -1531,17 +1528,12 @@ async def test_delete_dataset_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.DeleteDatasetRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_delete_dataset_async_from_dict(): - await test_delete_dataset_async(request_type=dict) - - def test_delete_dataset_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1551,7 +1543,7 @@ def test_delete_dataset_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.delete_dataset), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.delete_dataset(request) @@ -1576,7 +1568,9 @@ async def test_delete_dataset_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.delete_dataset), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -1597,7 +1591,7 @@ def test_delete_dataset_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + with mock.patch.object(type(client._transport.delete_dataset), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1629,7 +1623,9 @@ async def test_delete_dataset_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + with mock.patch.object( + type(client._client._transport.delete_dataset), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1670,7 +1666,7 @@ def test_import_data(transport: str = "grpc", request_type=service.ImportDataReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.import_data), "__call__") as call: + with mock.patch.object(type(client._transport.import_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -1691,19 +1687,19 @@ def test_import_data_from_dict(): @pytest.mark.asyncio -async def test_import_data_async( - transport: str = "grpc_asyncio", request_type=service.ImportDataRequest -): +async def test_import_data_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ImportDataRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.import_data), "__call__") as call: + with mock.patch.object( + type(client._client._transport.import_data), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -1715,17 +1711,12 @@ async def test_import_data_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ImportDataRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_import_data_async_from_dict(): - await test_import_data_async(request_type=dict) - - def test_import_data_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1735,7 +1726,7 @@ def test_import_data_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.import_data), "__call__") as call: + with mock.patch.object(type(client._transport.import_data), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.import_data(request) @@ -1760,7 +1751,9 @@ async def test_import_data_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.import_data), "__call__") as call: + with mock.patch.object( + type(client._client._transport.import_data), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -1781,7 +1774,7 @@ def test_import_data_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.import_data), "__call__") as call: + with mock.patch.object(type(client._transport.import_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1826,7 +1819,9 @@ async def test_import_data_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.import_data), "__call__") as call: + with mock.patch.object( + type(client._client._transport.import_data), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -1880,7 +1875,7 @@ def test_export_data(transport: str = "grpc", request_type=service.ExportDataReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_data), "__call__") as call: + with mock.patch.object(type(client._transport.export_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -1901,19 +1896,19 @@ def test_export_data_from_dict(): @pytest.mark.asyncio -async def test_export_data_async( - transport: str = "grpc_asyncio", request_type=service.ExportDataRequest -): +async def test_export_data_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ExportDataRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_data), "__call__") as call: + with mock.patch.object( + type(client._client._transport.export_data), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -1925,17 +1920,12 @@ async def test_export_data_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ExportDataRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_export_data_async_from_dict(): - await test_export_data_async(request_type=dict) - - def test_export_data_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -1945,7 +1935,7 @@ def test_export_data_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_data), "__call__") as call: + with mock.patch.object(type(client._transport.export_data), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.export_data(request) @@ -1970,7 +1960,9 @@ async def test_export_data_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_data), "__call__") as call: + with mock.patch.object( + type(client._client._transport.export_data), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -1991,7 +1983,7 @@ def test_export_data_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_data), "__call__") as call: + with mock.patch.object(type(client._transport.export_data), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -2042,7 +2034,9 @@ async def test_export_data_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_data), "__call__") as call: + with mock.patch.object( + type(client._client._transport.export_data), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -2105,7 +2099,7 @@ def test_get_annotation_spec( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_annotation_spec), "__call__" + type(client._transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = annotation_spec.AnnotationSpec( @@ -2121,7 +2115,6 @@ def test_get_annotation_spec( assert args[0] == service.GetAnnotationSpecRequest() # Establish that the response is the type that we expect. - assert isinstance(response, annotation_spec.AnnotationSpec) assert response.name == "name_value" @@ -2136,20 +2129,18 @@ def test_get_annotation_spec_from_dict(): @pytest.mark.asyncio -async def test_get_annotation_spec_async( - transport: str = "grpc_asyncio", request_type=service.GetAnnotationSpecRequest -): +async def test_get_annotation_spec_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.GetAnnotationSpecRequest() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_annotation_spec), "__call__" + type(client._client._transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -2166,7 +2157,7 @@ async def test_get_annotation_spec_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.GetAnnotationSpecRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, annotation_spec.AnnotationSpec) @@ -2178,11 +2169,6 @@ async def test_get_annotation_spec_async( assert response.example_count == 1396 -@pytest.mark.asyncio -async def test_get_annotation_spec_async_from_dict(): - await test_get_annotation_spec_async(request_type=dict) - - def test_get_annotation_spec_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2193,7 +2179,7 @@ def test_get_annotation_spec_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_annotation_spec), "__call__" + type(client._transport.get_annotation_spec), "__call__" ) as call: call.return_value = annotation_spec.AnnotationSpec() @@ -2220,7 +2206,7 @@ async def test_get_annotation_spec_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_annotation_spec), "__call__" + type(client._client._transport.get_annotation_spec), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( annotation_spec.AnnotationSpec() @@ -2243,7 +2229,7 @@ def test_get_annotation_spec_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_annotation_spec), "__call__" + type(client._transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = annotation_spec.AnnotationSpec() @@ -2277,7 +2263,7 @@ async def test_get_annotation_spec_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_annotation_spec), "__call__" + type(client._client._transport.get_annotation_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = annotation_spec.AnnotationSpec() @@ -2321,7 +2307,7 @@ def test_get_table_spec( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_table_spec), "__call__") as call: + with mock.patch.object(type(client._transport.get_table_spec), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = table_spec.TableSpec( name="name_value", @@ -2341,7 +2327,6 @@ def test_get_table_spec( assert args[0] == service.GetTableSpecRequest() # Establish that the response is the type that we expect. - assert isinstance(response, table_spec.TableSpec) assert response.name == "name_value" @@ -2362,19 +2347,19 @@ def test_get_table_spec_from_dict(): @pytest.mark.asyncio -async def test_get_table_spec_async( - transport: str = "grpc_asyncio", request_type=service.GetTableSpecRequest -): +async def test_get_table_spec_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.GetTableSpecRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_table_spec), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_table_spec), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( table_spec.TableSpec( @@ -2393,7 +2378,7 @@ async def test_get_table_spec_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.GetTableSpecRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, table_spec.TableSpec) @@ -2411,11 +2396,6 @@ async def test_get_table_spec_async( assert response.etag == "etag_value" -@pytest.mark.asyncio -async def test_get_table_spec_async_from_dict(): - await test_get_table_spec_async(request_type=dict) - - def test_get_table_spec_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2425,7 +2405,7 @@ def test_get_table_spec_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_table_spec), "__call__") as call: + with mock.patch.object(type(client._transport.get_table_spec), "__call__") as call: call.return_value = table_spec.TableSpec() client.get_table_spec(request) @@ -2450,7 +2430,9 @@ async def test_get_table_spec_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_table_spec), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_table_spec), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( table_spec.TableSpec() ) @@ -2471,7 +2453,7 @@ def test_get_table_spec_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_table_spec), "__call__") as call: + with mock.patch.object(type(client._transport.get_table_spec), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = table_spec.TableSpec() @@ -2503,7 +2485,9 @@ async def test_get_table_spec_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_table_spec), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_table_spec), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = table_spec.TableSpec() @@ -2546,7 +2530,9 @@ def test_list_table_specs( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: + with mock.patch.object( + type(client._transport.list_table_specs), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListTableSpecsResponse( next_page_token="next_page_token_value", @@ -2561,7 +2547,6 @@ def test_list_table_specs( assert args[0] == service.ListTableSpecsRequest() # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListTableSpecsPager) assert response.next_page_token == "next_page_token_value" @@ -2572,19 +2557,19 @@ def test_list_table_specs_from_dict(): @pytest.mark.asyncio -async def test_list_table_specs_async( - transport: str = "grpc_asyncio", request_type=service.ListTableSpecsRequest -): +async def test_list_table_specs_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ListTableSpecsRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_table_specs), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListTableSpecsResponse(next_page_token="next_page_token_value",) @@ -2596,7 +2581,7 @@ async def test_list_table_specs_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ListTableSpecsRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListTableSpecsAsyncPager) @@ -2604,11 +2589,6 @@ async def test_list_table_specs_async( assert response.next_page_token == "next_page_token_value" -@pytest.mark.asyncio -async def test_list_table_specs_async_from_dict(): - await test_list_table_specs_async(request_type=dict) - - def test_list_table_specs_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2618,7 +2598,9 @@ def test_list_table_specs_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: + with mock.patch.object( + type(client._transport.list_table_specs), "__call__" + ) as call: call.return_value = service.ListTableSpecsResponse() client.list_table_specs(request) @@ -2643,7 +2625,9 @@ async def test_list_table_specs_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_table_specs), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListTableSpecsResponse() ) @@ -2664,7 +2648,9 @@ def test_list_table_specs_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: + with mock.patch.object( + type(client._transport.list_table_specs), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListTableSpecsResponse() @@ -2696,7 +2682,9 @@ async def test_list_table_specs_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_table_specs), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListTableSpecsResponse() @@ -2731,7 +2719,9 @@ def test_list_table_specs_pager(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: + with mock.patch.object( + type(client._transport.list_table_specs), "__call__" + ) as call: # Set the response to a series of pages. call.side_effect = ( service.ListTableSpecsResponse( @@ -2769,7 +2759,9 @@ def test_list_table_specs_pages(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_table_specs), "__call__") as call: + with mock.patch.object( + type(client._transport.list_table_specs), "__call__" + ) as call: # Set the response to a series of pages. call.side_effect = ( service.ListTableSpecsResponse( @@ -2800,7 +2792,9 @@ async def test_list_table_specs_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_table_specs), "__call__", new_callable=mock.AsyncMock + type(client._client._transport.list_table_specs), + "__call__", + new_callable=mock.AsyncMock, ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -2837,7 +2831,9 @@ async def test_list_table_specs_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_table_specs), "__call__", new_callable=mock.AsyncMock + type(client._client._transport.list_table_specs), + "__call__", + new_callable=mock.AsyncMock, ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -2878,7 +2874,7 @@ def test_update_table_spec( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.update_table_spec), "__call__" + type(client._transport.update_table_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = gca_table_spec.TableSpec( @@ -2899,7 +2895,6 @@ def test_update_table_spec( assert args[0] == service.UpdateTableSpecRequest() # Establish that the response is the type that we expect. - assert isinstance(response, gca_table_spec.TableSpec) assert response.name == "name_value" @@ -2920,20 +2915,18 @@ def test_update_table_spec_from_dict(): @pytest.mark.asyncio -async def test_update_table_spec_async( - transport: str = "grpc_asyncio", request_type=service.UpdateTableSpecRequest -): +async def test_update_table_spec_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.UpdateTableSpecRequest() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.update_table_spec), "__call__" + type(client._client._transport.update_table_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -2953,7 +2946,7 @@ async def test_update_table_spec_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.UpdateTableSpecRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, gca_table_spec.TableSpec) @@ -2971,11 +2964,6 @@ async def test_update_table_spec_async( assert response.etag == "etag_value" -@pytest.mark.asyncio -async def test_update_table_spec_async_from_dict(): - await test_update_table_spec_async(request_type=dict) - - def test_update_table_spec_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -2986,7 +2974,7 @@ def test_update_table_spec_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.update_table_spec), "__call__" + type(client._transport.update_table_spec), "__call__" ) as call: call.return_value = gca_table_spec.TableSpec() @@ -3015,7 +3003,7 @@ async def test_update_table_spec_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.update_table_spec), "__call__" + type(client._client._transport.update_table_spec), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( gca_table_spec.TableSpec() @@ -3040,7 +3028,7 @@ def test_update_table_spec_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.update_table_spec), "__call__" + type(client._transport.update_table_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = gca_table_spec.TableSpec() @@ -3077,7 +3065,7 @@ async def test_update_table_spec_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.update_table_spec), "__call__" + type(client._client._transport.update_table_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = gca_table_spec.TableSpec() @@ -3124,7 +3112,7 @@ def test_get_column_spec( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_column_spec), "__call__") as call: + with mock.patch.object(type(client._transport.get_column_spec), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = column_spec.ColumnSpec( name="name_value", display_name="display_name_value", etag="etag_value", @@ -3139,7 +3127,6 @@ def test_get_column_spec( assert args[0] == service.GetColumnSpecRequest() # Establish that the response is the type that we expect. - assert isinstance(response, column_spec.ColumnSpec) assert response.name == "name_value" @@ -3154,19 +3141,19 @@ def test_get_column_spec_from_dict(): @pytest.mark.asyncio -async def test_get_column_spec_async( - transport: str = "grpc_asyncio", request_type=service.GetColumnSpecRequest -): +async def test_get_column_spec_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.GetColumnSpecRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_column_spec), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_column_spec), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( column_spec.ColumnSpec( @@ -3180,7 +3167,7 @@ async def test_get_column_spec_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.GetColumnSpecRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, column_spec.ColumnSpec) @@ -3192,11 +3179,6 @@ async def test_get_column_spec_async( assert response.etag == "etag_value" -@pytest.mark.asyncio -async def test_get_column_spec_async_from_dict(): - await test_get_column_spec_async(request_type=dict) - - def test_get_column_spec_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3206,7 +3188,7 @@ def test_get_column_spec_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_column_spec), "__call__") as call: + with mock.patch.object(type(client._transport.get_column_spec), "__call__") as call: call.return_value = column_spec.ColumnSpec() client.get_column_spec(request) @@ -3231,7 +3213,9 @@ async def test_get_column_spec_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_column_spec), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_column_spec), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( column_spec.ColumnSpec() ) @@ -3252,7 +3236,7 @@ def test_get_column_spec_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_column_spec), "__call__") as call: + with mock.patch.object(type(client._transport.get_column_spec), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = column_spec.ColumnSpec() @@ -3284,7 +3268,9 @@ async def test_get_column_spec_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_column_spec), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_column_spec), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = column_spec.ColumnSpec() @@ -3328,7 +3314,7 @@ def test_list_column_specs( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_column_specs), "__call__" + type(client._transport.list_column_specs), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListColumnSpecsResponse( @@ -3344,7 +3330,6 @@ def test_list_column_specs( assert args[0] == service.ListColumnSpecsRequest() # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListColumnSpecsPager) assert response.next_page_token == "next_page_token_value" @@ -3355,20 +3340,18 @@ def test_list_column_specs_from_dict(): @pytest.mark.asyncio -async def test_list_column_specs_async( - transport: str = "grpc_asyncio", request_type=service.ListColumnSpecsRequest -): +async def test_list_column_specs_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ListColumnSpecsRequest() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_column_specs), "__call__" + type(client._client._transport.list_column_specs), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -3381,7 +3364,7 @@ async def test_list_column_specs_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ListColumnSpecsRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListColumnSpecsAsyncPager) @@ -3389,11 +3372,6 @@ async def test_list_column_specs_async( assert response.next_page_token == "next_page_token_value" -@pytest.mark.asyncio -async def test_list_column_specs_async_from_dict(): - await test_list_column_specs_async(request_type=dict) - - def test_list_column_specs_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3404,7 +3382,7 @@ def test_list_column_specs_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_column_specs), "__call__" + type(client._transport.list_column_specs), "__call__" ) as call: call.return_value = service.ListColumnSpecsResponse() @@ -3431,7 +3409,7 @@ async def test_list_column_specs_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_column_specs), "__call__" + type(client._client._transport.list_column_specs), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListColumnSpecsResponse() @@ -3454,7 +3432,7 @@ def test_list_column_specs_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_column_specs), "__call__" + type(client._transport.list_column_specs), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListColumnSpecsResponse() @@ -3488,7 +3466,7 @@ async def test_list_column_specs_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_column_specs), "__call__" + type(client._client._transport.list_column_specs), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListColumnSpecsResponse() @@ -3525,7 +3503,7 @@ def test_list_column_specs_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_column_specs), "__call__" + type(client._transport.list_column_specs), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -3565,7 +3543,7 @@ def test_list_column_specs_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_column_specs), "__call__" + type(client._transport.list_column_specs), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -3597,7 +3575,7 @@ async def test_list_column_specs_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_column_specs), + type(client._client._transport.list_column_specs), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -3636,7 +3614,7 @@ async def test_list_column_specs_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_column_specs), + type(client._client._transport.list_column_specs), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -3679,7 +3657,7 @@ def test_update_column_spec( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.update_column_spec), "__call__" + type(client._transport.update_column_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = gca_column_spec.ColumnSpec( @@ -3695,7 +3673,6 @@ def test_update_column_spec( assert args[0] == service.UpdateColumnSpecRequest() # Establish that the response is the type that we expect. - assert isinstance(response, gca_column_spec.ColumnSpec) assert response.name == "name_value" @@ -3710,20 +3687,18 @@ def test_update_column_spec_from_dict(): @pytest.mark.asyncio -async def test_update_column_spec_async( - transport: str = "grpc_asyncio", request_type=service.UpdateColumnSpecRequest -): +async def test_update_column_spec_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.UpdateColumnSpecRequest() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.update_column_spec), "__call__" + type(client._client._transport.update_column_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -3738,7 +3713,7 @@ async def test_update_column_spec_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.UpdateColumnSpecRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, gca_column_spec.ColumnSpec) @@ -3750,11 +3725,6 @@ async def test_update_column_spec_async( assert response.etag == "etag_value" -@pytest.mark.asyncio -async def test_update_column_spec_async_from_dict(): - await test_update_column_spec_async(request_type=dict) - - def test_update_column_spec_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3765,7 +3735,7 @@ def test_update_column_spec_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.update_column_spec), "__call__" + type(client._transport.update_column_spec), "__call__" ) as call: call.return_value = gca_column_spec.ColumnSpec() @@ -3794,7 +3764,7 @@ async def test_update_column_spec_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.update_column_spec), "__call__" + type(client._client._transport.update_column_spec), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( gca_column_spec.ColumnSpec() @@ -3819,7 +3789,7 @@ def test_update_column_spec_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.update_column_spec), "__call__" + type(client._transport.update_column_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = gca_column_spec.ColumnSpec() @@ -3856,7 +3826,7 @@ async def test_update_column_spec_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.update_column_spec), "__call__" + type(client._client._transport.update_column_spec), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = gca_column_spec.ColumnSpec() @@ -3901,7 +3871,7 @@ def test_create_model(transport: str = "grpc", request_type=service.CreateModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_model), "__call__") as call: + with mock.patch.object(type(client._transport.create_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -3922,19 +3892,19 @@ def test_create_model_from_dict(): @pytest.mark.asyncio -async def test_create_model_async( - transport: str = "grpc_asyncio", request_type=service.CreateModelRequest -): +async def test_create_model_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.CreateModelRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.create_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -3946,17 +3916,12 @@ async def test_create_model_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.CreateModelRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_create_model_async_from_dict(): - await test_create_model_async(request_type=dict) - - def test_create_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -3966,7 +3931,7 @@ def test_create_model_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_model), "__call__") as call: + with mock.patch.object(type(client._transport.create_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.create_model(request) @@ -3991,7 +3956,9 @@ async def test_create_model_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.create_model), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -4012,7 +3979,7 @@ def test_create_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_model), "__call__") as call: + with mock.patch.object(type(client._transport.create_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -4063,7 +4030,9 @@ async def test_create_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.create_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -4123,7 +4092,7 @@ def test_get_model(transport: str = "grpc", request_type=service.GetModelRequest request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_model), "__call__") as call: + with mock.patch.object(type(client._transport.get_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = model.Model( name="name_value", @@ -4144,7 +4113,6 @@ def test_get_model(transport: str = "grpc", request_type=service.GetModelRequest assert args[0] == service.GetModelRequest() # Establish that the response is the type that we expect. - assert isinstance(response, model.Model) assert response.name == "name_value" @@ -4161,19 +4129,19 @@ def test_get_model_from_dict(): @pytest.mark.asyncio -async def test_get_model_async( - transport: str = "grpc_asyncio", request_type=service.GetModelRequest -): +async def test_get_model_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.GetModelRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( model.Model( @@ -4190,7 +4158,7 @@ async def test_get_model_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.GetModelRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, model.Model) @@ -4204,11 +4172,6 @@ async def test_get_model_async( assert response.deployment_state == model.Model.DeploymentState.DEPLOYED -@pytest.mark.asyncio -async def test_get_model_async_from_dict(): - await test_get_model_async(request_type=dict) - - def test_get_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4218,7 +4181,7 @@ def test_get_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_model), "__call__") as call: + with mock.patch.object(type(client._transport.get_model), "__call__") as call: call.return_value = model.Model() client.get_model(request) @@ -4243,7 +4206,9 @@ async def test_get_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_model), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) await client.get_model(request) @@ -4262,7 +4227,7 @@ def test_get_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_model), "__call__") as call: + with mock.patch.object(type(client._transport.get_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = model.Model() @@ -4294,7 +4259,9 @@ async def test_get_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.get_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = model.Model() @@ -4333,7 +4300,7 @@ def test_list_models(transport: str = "grpc", request_type=service.ListModelsReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object(type(client._transport.list_models), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelsResponse( next_page_token="next_page_token_value", @@ -4348,7 +4315,6 @@ def test_list_models(transport: str = "grpc", request_type=service.ListModelsReq assert args[0] == service.ListModelsRequest() # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListModelsPager) assert response.next_page_token == "next_page_token_value" @@ -4359,19 +4325,19 @@ def test_list_models_from_dict(): @pytest.mark.asyncio -async def test_list_models_async( - transport: str = "grpc_asyncio", request_type=service.ListModelsRequest -): +async def test_list_models_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ListModelsRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_models), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListModelsResponse(next_page_token="next_page_token_value",) @@ -4383,7 +4349,7 @@ async def test_list_models_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ListModelsRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListModelsAsyncPager) @@ -4391,11 +4357,6 @@ async def test_list_models_async( assert response.next_page_token == "next_page_token_value" -@pytest.mark.asyncio -async def test_list_models_async_from_dict(): - await test_list_models_async(request_type=dict) - - def test_list_models_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4405,7 +4366,7 @@ def test_list_models_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object(type(client._transport.list_models), "__call__") as call: call.return_value = service.ListModelsResponse() client.list_models(request) @@ -4430,7 +4391,9 @@ async def test_list_models_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_models), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListModelsResponse() ) @@ -4451,7 +4414,7 @@ def test_list_models_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object(type(client._transport.list_models), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelsResponse() @@ -4483,7 +4446,9 @@ async def test_list_models_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object( + type(client._client._transport.list_models), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelsResponse() @@ -4518,7 +4483,7 @@ def test_list_models_pager(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object(type(client._transport.list_models), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListModelsResponse( @@ -4548,7 +4513,7 @@ def test_list_models_pages(): client = AutoMlClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_models), "__call__") as call: + with mock.patch.object(type(client._transport.list_models), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( service.ListModelsResponse( @@ -4571,7 +4536,9 @@ async def test_list_models_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_models), "__call__", new_callable=mock.AsyncMock + type(client._client._transport.list_models), + "__call__", + new_callable=mock.AsyncMock, ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -4600,7 +4567,9 @@ async def test_list_models_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_models), "__call__", new_callable=mock.AsyncMock + type(client._client._transport.list_models), + "__call__", + new_callable=mock.AsyncMock, ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -4630,7 +4599,7 @@ def test_delete_model(transport: str = "grpc", request_type=service.DeleteModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + with mock.patch.object(type(client._transport.delete_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -4651,19 +4620,19 @@ def test_delete_model_from_dict(): @pytest.mark.asyncio -async def test_delete_model_async( - transport: str = "grpc_asyncio", request_type=service.DeleteModelRequest -): +async def test_delete_model_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.DeleteModelRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.delete_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -4675,17 +4644,12 @@ async def test_delete_model_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.DeleteModelRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_delete_model_async_from_dict(): - await test_delete_model_async(request_type=dict) - - def test_delete_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4695,7 +4659,7 @@ def test_delete_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + with mock.patch.object(type(client._transport.delete_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.delete_model(request) @@ -4720,7 +4684,9 @@ async def test_delete_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.delete_model), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -4741,7 +4707,7 @@ def test_delete_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + with mock.patch.object(type(client._transport.delete_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -4773,7 +4739,9 @@ async def test_delete_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.delete_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -4814,7 +4782,7 @@ def test_deploy_model(transport: str = "grpc", request_type=service.DeployModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: + with mock.patch.object(type(client._transport.deploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -4835,19 +4803,19 @@ def test_deploy_model_from_dict(): @pytest.mark.asyncio -async def test_deploy_model_async( - transport: str = "grpc_asyncio", request_type=service.DeployModelRequest -): +async def test_deploy_model_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.DeployModelRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.deploy_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -4859,17 +4827,12 @@ async def test_deploy_model_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.DeployModelRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_deploy_model_async_from_dict(): - await test_deploy_model_async(request_type=dict) - - def test_deploy_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -4879,7 +4842,7 @@ def test_deploy_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: + with mock.patch.object(type(client._transport.deploy_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.deploy_model(request) @@ -4904,7 +4867,9 @@ async def test_deploy_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.deploy_model), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -4925,7 +4890,7 @@ def test_deploy_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: + with mock.patch.object(type(client._transport.deploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -4957,7 +4922,9 @@ async def test_deploy_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.deploy_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.deploy_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -5000,7 +4967,7 @@ def test_undeploy_model( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: + with mock.patch.object(type(client._transport.undeploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -5021,19 +4988,19 @@ def test_undeploy_model_from_dict(): @pytest.mark.asyncio -async def test_undeploy_model_async( - transport: str = "grpc_asyncio", request_type=service.UndeployModelRequest -): +async def test_undeploy_model_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.UndeployModelRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.undeploy_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -5045,17 +5012,12 @@ async def test_undeploy_model_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.UndeployModelRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_undeploy_model_async_from_dict(): - await test_undeploy_model_async(request_type=dict) - - def test_undeploy_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -5065,7 +5027,7 @@ def test_undeploy_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: + with mock.patch.object(type(client._transport.undeploy_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.undeploy_model(request) @@ -5090,7 +5052,9 @@ async def test_undeploy_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.undeploy_model), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -5111,7 +5075,7 @@ def test_undeploy_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: + with mock.patch.object(type(client._transport.undeploy_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -5143,7 +5107,9 @@ async def test_undeploy_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.undeploy_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.undeploy_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -5184,7 +5150,7 @@ def test_export_model(transport: str = "grpc", request_type=service.ExportModelR request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_model), "__call__") as call: + with mock.patch.object(type(client._transport.export_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -5205,19 +5171,19 @@ def test_export_model_from_dict(): @pytest.mark.asyncio -async def test_export_model_async( - transport: str = "grpc_asyncio", request_type=service.ExportModelRequest -): +async def test_export_model_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ExportModelRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.export_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -5229,17 +5195,12 @@ async def test_export_model_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ExportModelRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_export_model_async_from_dict(): - await test_export_model_async(request_type=dict) - - def test_export_model_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -5249,7 +5210,7 @@ def test_export_model_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_model), "__call__") as call: + with mock.patch.object(type(client._transport.export_model), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.export_model(request) @@ -5274,7 +5235,9 @@ async def test_export_model_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.export_model), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -5295,7 +5258,7 @@ def test_export_model_flattened(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_model), "__call__") as call: + with mock.patch.object(type(client._transport.export_model), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -5346,7 +5309,9 @@ async def test_export_model_flattened_async(): client = AutoMlAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.export_model), "__call__") as call: + with mock.patch.object( + type(client._client._transport.export_model), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -5409,7 +5374,7 @@ def test_export_evaluated_examples( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.export_evaluated_examples), "__call__" + type(client._transport.export_evaluated_examples), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -5431,20 +5396,18 @@ def test_export_evaluated_examples_from_dict(): @pytest.mark.asyncio -async def test_export_evaluated_examples_async( - transport: str = "grpc_asyncio", request_type=service.ExportEvaluatedExamplesRequest -): +async def test_export_evaluated_examples_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ExportEvaluatedExamplesRequest() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.export_evaluated_examples), "__call__" + type(client._client._transport.export_evaluated_examples), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -5457,17 +5420,12 @@ async def test_export_evaluated_examples_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ExportEvaluatedExamplesRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_export_evaluated_examples_async_from_dict(): - await test_export_evaluated_examples_async(request_type=dict) - - def test_export_evaluated_examples_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -5478,7 +5436,7 @@ def test_export_evaluated_examples_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.export_evaluated_examples), "__call__" + type(client._transport.export_evaluated_examples), "__call__" ) as call: call.return_value = operations_pb2.Operation(name="operations/op") @@ -5505,7 +5463,7 @@ async def test_export_evaluated_examples_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.export_evaluated_examples), "__call__" + type(client._client._transport.export_evaluated_examples), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") @@ -5528,7 +5486,7 @@ def test_export_evaluated_examples_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.export_evaluated_examples), "__call__" + type(client._transport.export_evaluated_examples), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -5579,7 +5537,7 @@ async def test_export_evaluated_examples_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.export_evaluated_examples), "__call__" + type(client._client._transport.export_evaluated_examples), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -5641,7 +5599,7 @@ def test_get_model_evaluation( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_model_evaluation), "__call__" + type(client._transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = model_evaluation.ModelEvaluation( @@ -5663,7 +5621,6 @@ def test_get_model_evaluation( assert args[0] == service.GetModelEvaluationRequest() # Establish that the response is the type that we expect. - assert isinstance(response, model_evaluation.ModelEvaluation) assert response.name == "name_value" @@ -5680,20 +5637,18 @@ def test_get_model_evaluation_from_dict(): @pytest.mark.asyncio -async def test_get_model_evaluation_async( - transport: str = "grpc_asyncio", request_type=service.GetModelEvaluationRequest -): +async def test_get_model_evaluation_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.GetModelEvaluationRequest() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_model_evaluation), "__call__" + type(client._client._transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -5711,7 +5666,7 @@ async def test_get_model_evaluation_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.GetModelEvaluationRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, model_evaluation.ModelEvaluation) @@ -5725,11 +5680,6 @@ async def test_get_model_evaluation_async( assert response.evaluated_example_count == 2446 -@pytest.mark.asyncio -async def test_get_model_evaluation_async_from_dict(): - await test_get_model_evaluation_async(request_type=dict) - - def test_get_model_evaluation_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -5740,7 +5690,7 @@ def test_get_model_evaluation_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_model_evaluation), "__call__" + type(client._transport.get_model_evaluation), "__call__" ) as call: call.return_value = model_evaluation.ModelEvaluation() @@ -5767,7 +5717,7 @@ async def test_get_model_evaluation_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_model_evaluation), "__call__" + type(client._client._transport.get_model_evaluation), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( model_evaluation.ModelEvaluation() @@ -5790,7 +5740,7 @@ def test_get_model_evaluation_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_model_evaluation), "__call__" + type(client._transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = model_evaluation.ModelEvaluation() @@ -5824,7 +5774,7 @@ async def test_get_model_evaluation_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.get_model_evaluation), "__call__" + type(client._client._transport.get_model_evaluation), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = model_evaluation.ModelEvaluation() @@ -5869,7 +5819,7 @@ def test_list_model_evaluations( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelEvaluationsResponse( @@ -5885,7 +5835,6 @@ def test_list_model_evaluations( assert args[0] == service.ListModelEvaluationsRequest() # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListModelEvaluationsPager) assert response.next_page_token == "next_page_token_value" @@ -5896,20 +5845,18 @@ def test_list_model_evaluations_from_dict(): @pytest.mark.asyncio -async def test_list_model_evaluations_async( - transport: str = "grpc_asyncio", request_type=service.ListModelEvaluationsRequest -): +async def test_list_model_evaluations_async(transport: str = "grpc_asyncio"): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = service.ListModelEvaluationsRequest() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._client._transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -5924,7 +5871,7 @@ async def test_list_model_evaluations_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == service.ListModelEvaluationsRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListModelEvaluationsAsyncPager) @@ -5932,11 +5879,6 @@ async def test_list_model_evaluations_async( assert response.next_page_token == "next_page_token_value" -@pytest.mark.asyncio -async def test_list_model_evaluations_async_from_dict(): - await test_list_model_evaluations_async(request_type=dict) - - def test_list_model_evaluations_field_headers(): client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) @@ -5947,7 +5889,7 @@ def test_list_model_evaluations_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._transport.list_model_evaluations), "__call__" ) as call: call.return_value = service.ListModelEvaluationsResponse() @@ -5974,7 +5916,7 @@ async def test_list_model_evaluations_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._client._transport.list_model_evaluations), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( service.ListModelEvaluationsResponse() @@ -5997,7 +5939,7 @@ def test_list_model_evaluations_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelEvaluationsResponse() @@ -6031,7 +5973,7 @@ async def test_list_model_evaluations_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._client._transport.list_model_evaluations), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = service.ListModelEvaluationsResponse() @@ -6068,7 +6010,7 @@ def test_list_model_evaluations_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._transport.list_model_evaluations), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -6114,7 +6056,7 @@ def test_list_model_evaluations_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), "__call__" + type(client._transport.list_model_evaluations), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -6152,7 +6094,7 @@ async def test_list_model_evaluations_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), + type(client._client._transport.list_model_evaluations), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -6197,7 +6139,7 @@ async def test_list_model_evaluations_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.list_model_evaluations), + type(client._client._transport.list_model_evaluations), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -6269,7 +6211,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = AutoMlClient(transport=transport) - assert client.transport is transport + assert client._transport is transport def test_transport_get_channel(): @@ -6302,7 +6244,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AutoMlClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client.transport, transports.AutoMlGrpcTransport,) + assert isinstance(client._transport, transports.AutoMlGrpcTransport,) def test_auto_ml_base_transport_error(): @@ -6424,7 +6366,7 @@ def test_auto_ml_host_no_port(): api_endpoint="automl.googleapis.com" ), ) - assert client.transport._host == "automl.googleapis.com:443" + assert client._transport._host == "automl.googleapis.com:443" def test_auto_ml_host_with_port(): @@ -6434,7 +6376,7 @@ def test_auto_ml_host_with_port(): api_endpoint="automl.googleapis.com:8000" ), ) - assert client.transport._host == "automl.googleapis.com:8000" + assert client._transport._host == "automl.googleapis.com:8000" def test_auto_ml_grpc_transport_channel(): @@ -6542,7 +6484,7 @@ def test_auto_ml_grpc_lro_client(): client = AutoMlClient( credentials=credentials.AnonymousCredentials(), transport="grpc", ) - transport = client.transport + transport = client._transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsClient,) @@ -6555,7 +6497,7 @@ def test_auto_ml_grpc_lro_async_client(): client = AutoMlAsyncClient( credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", ) - transport = client.transport + transport = client._client._transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,) @@ -6564,44 +6506,12 @@ def test_auto_ml_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_annotation_spec_path(): +def test_column_spec_path(): project = "squid" location = "clam" dataset = "whelk" - annotation_spec = "octopus" - - expected = "projects/{project}/locations/{location}/datasets/{dataset}/annotationSpecs/{annotation_spec}".format( - project=project, - location=location, - dataset=dataset, - annotation_spec=annotation_spec, - ) - actual = AutoMlClient.annotation_spec_path( - project, location, dataset, annotation_spec - ) - assert expected == actual - - -def test_parse_annotation_spec_path(): - expected = { - "project": "oyster", - "location": "nudibranch", - "dataset": "cuttlefish", - "annotation_spec": "mussel", - } - path = AutoMlClient.annotation_spec_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_annotation_spec_path(path) - assert expected == actual - - -def test_column_spec_path(): - project = "winkle" - location = "nautilus" - dataset = "scallop" - table_spec = "abalone" - column_spec = "squid" + table_spec = "octopus" + column_spec = "oyster" expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}/columnSpecs/{column_spec}".format( project=project, @@ -6618,11 +6528,11 @@ def test_column_spec_path(): def test_parse_column_spec_path(): expected = { - "project": "clam", - "location": "whelk", - "dataset": "octopus", - "table_spec": "oyster", - "column_spec": "nudibranch", + "project": "nudibranch", + "location": "cuttlefish", + "dataset": "mussel", + "table_spec": "winkle", + "column_spec": "nautilus", } path = AutoMlClient.column_spec_path(**expected) @@ -6632,9 +6542,9 @@ def test_parse_column_spec_path(): def test_dataset_path(): - project = "cuttlefish" - location = "mussel" - dataset = "winkle" + project = "squid" + location = "clam" + dataset = "whelk" expected = "projects/{project}/locations/{location}/datasets/{dataset}".format( project=project, location=location, dataset=dataset, @@ -6645,9 +6555,9 @@ def test_dataset_path(): def test_parse_dataset_path(): expected = { - "project": "nautilus", - "location": "scallop", - "dataset": "abalone", + "project": "octopus", + "location": "oyster", + "dataset": "nudibranch", } path = AutoMlClient.dataset_path(**expected) @@ -6681,43 +6591,11 @@ def test_parse_model_path(): assert expected == actual -def test_model_evaluation_path(): - project = "cuttlefish" - location = "mussel" - model = "winkle" - model_evaluation = "nautilus" - - expected = "projects/{project}/locations/{location}/models/{model}/modelEvaluations/{model_evaluation}".format( - project=project, - location=location, - model=model, - model_evaluation=model_evaluation, - ) - actual = AutoMlClient.model_evaluation_path( - project, location, model, model_evaluation - ) - assert expected == actual - - -def test_parse_model_evaluation_path(): - expected = { - "project": "scallop", - "location": "abalone", - "model": "squid", - "model_evaluation": "clam", - } - path = AutoMlClient.model_evaluation_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_model_evaluation_path(path) - assert expected == actual - - def test_table_spec_path(): - project = "whelk" - location = "octopus" - dataset = "oyster" - table_spec = "nudibranch" + project = "squid" + location = "clam" + dataset = "whelk" + table_spec = "octopus" expected = "projects/{project}/locations/{location}/datasets/{dataset}/tableSpecs/{table_spec}".format( project=project, location=location, dataset=dataset, table_spec=table_spec, @@ -6728,10 +6606,10 @@ def test_table_spec_path(): def test_parse_table_spec_path(): expected = { - "project": "cuttlefish", - "location": "mussel", - "dataset": "winkle", - "table_spec": "nautilus", + "project": "oyster", + "location": "nudibranch", + "dataset": "cuttlefish", + "table_spec": "mussel", } path = AutoMlClient.table_spec_path(**expected) @@ -6740,107 +6618,6 @@ def test_parse_table_spec_path(): assert expected == actual -def test_common_billing_account_path(): - billing_account = "scallop" - - expected = "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - actual = AutoMlClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "abalone", - } - path = AutoMlClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_common_billing_account_path(path) - assert expected == actual - - -def test_common_folder_path(): - folder = "squid" - - expected = "folders/{folder}".format(folder=folder,) - actual = AutoMlClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "clam", - } - path = AutoMlClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_common_folder_path(path) - assert expected == actual - - -def test_common_organization_path(): - organization = "whelk" - - expected = "organizations/{organization}".format(organization=organization,) - actual = AutoMlClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "octopus", - } - path = AutoMlClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_common_organization_path(path) - assert expected == actual - - -def test_common_project_path(): - project = "oyster" - - expected = "projects/{project}".format(project=project,) - actual = AutoMlClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "nudibranch", - } - path = AutoMlClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_common_project_path(path) - assert expected == actual - - -def test_common_location_path(): - project = "cuttlefish" - location = "mussel" - - expected = "projects/{project}/locations/{location}".format( - project=project, location=location, - ) - actual = AutoMlClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "winkle", - "location": "nautilus", - } - path = AutoMlClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = AutoMlClient.parse_common_location_path(path) - assert expected == actual - - def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() diff --git a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py index 4a9c2a22..44c966c5 100644 --- a/tests/unit/gapic/automl_v1beta1/test_prediction_service.py +++ b/tests/unit/gapic/automl_v1beta1/test_prediction_service.py @@ -109,12 +109,12 @@ def test_prediction_service_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client.transport._credentials == creds + assert client._transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client.transport._credentials == creds + assert client._transport._credentials == creds - assert client.transport._host == "automl.googleapis.com:443" + assert client._transport._host == "automl.googleapis.com:443" def test_prediction_service_client_get_transport_class(): @@ -474,7 +474,7 @@ def test_predict( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.predict), "__call__") as call: + with mock.patch.object(type(client._transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = prediction_service.PredictResponse() @@ -487,7 +487,6 @@ def test_predict( assert args[0] == prediction_service.PredictRequest() # Establish that the response is the type that we expect. - assert isinstance(response, prediction_service.PredictResponse) @@ -496,19 +495,17 @@ def test_predict_from_dict(): @pytest.mark.asyncio -async def test_predict_async( - transport: str = "grpc_asyncio", request_type=prediction_service.PredictRequest -): +async def test_predict_async(transport: str = "grpc_asyncio"): client = PredictionServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = prediction_service.PredictRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.predict), "__call__") as call: + with mock.patch.object(type(client._client._transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( prediction_service.PredictResponse() @@ -520,17 +517,12 @@ async def test_predict_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == prediction_service.PredictRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, prediction_service.PredictResponse) -@pytest.mark.asyncio -async def test_predict_async_from_dict(): - await test_predict_async(request_type=dict) - - def test_predict_field_headers(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -540,7 +532,7 @@ def test_predict_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.predict), "__call__") as call: + with mock.patch.object(type(client._transport.predict), "__call__") as call: call.return_value = prediction_service.PredictResponse() client.predict(request) @@ -567,7 +559,7 @@ async def test_predict_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.predict), "__call__") as call: + with mock.patch.object(type(client._client._transport.predict), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( prediction_service.PredictResponse() ) @@ -588,7 +580,7 @@ def test_predict_flattened(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.predict), "__call__") as call: + with mock.patch.object(type(client._transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = prediction_service.PredictResponse() @@ -639,7 +631,7 @@ async def test_predict_flattened_async(): ) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.predict), "__call__") as call: + with mock.patch.object(type(client._client._transport.predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = prediction_service.PredictResponse() @@ -701,7 +693,7 @@ def test_batch_predict( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: + with mock.patch.object(type(client._transport.batch_predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -722,19 +714,19 @@ def test_batch_predict_from_dict(): @pytest.mark.asyncio -async def test_batch_predict_async( - transport: str = "grpc_asyncio", request_type=prediction_service.BatchPredictRequest -): +async def test_batch_predict_async(transport: str = "grpc_asyncio"): client = PredictionServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = request_type() + request = prediction_service.BatchPredictRequest() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: + with mock.patch.object( + type(client._client._transport.batch_predict), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -746,17 +738,12 @@ async def test_batch_predict_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == prediction_service.BatchPredictRequest() + assert args[0] == request # Establish that the response is the type that we expect. assert isinstance(response, future.Future) -@pytest.mark.asyncio -async def test_batch_predict_async_from_dict(): - await test_batch_predict_async(request_type=dict) - - def test_batch_predict_field_headers(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -766,7 +753,7 @@ def test_batch_predict_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: + with mock.patch.object(type(client._transport.batch_predict), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.batch_predict(request) @@ -793,7 +780,9 @@ async def test_batch_predict_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: + with mock.patch.object( + type(client._client._transport.batch_predict), "__call__" + ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -814,7 +803,7 @@ def test_batch_predict_flattened(): client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: + with mock.patch.object(type(client._transport.batch_predict), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -881,7 +870,9 @@ async def test_batch_predict_flattened_async(): ) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.batch_predict), "__call__") as call: + with mock.patch.object( + type(client._client._transport.batch_predict), "__call__" + ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") @@ -983,7 +974,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = PredictionServiceClient(transport=transport) - assert client.transport is transport + assert client._transport is transport def test_transport_get_channel(): @@ -1019,7 +1010,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = PredictionServiceClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client.transport, transports.PredictionServiceGrpcTransport,) + assert isinstance(client._transport, transports.PredictionServiceGrpcTransport,) def test_prediction_service_base_transport_error(): @@ -1119,7 +1110,7 @@ def test_prediction_service_host_no_port(): api_endpoint="automl.googleapis.com" ), ) - assert client.transport._host == "automl.googleapis.com:443" + assert client._transport._host == "automl.googleapis.com:443" def test_prediction_service_host_with_port(): @@ -1129,7 +1120,7 @@ def test_prediction_service_host_with_port(): api_endpoint="automl.googleapis.com:8000" ), ) - assert client.transport._host == "automl.googleapis.com:8000" + assert client._transport._host == "automl.googleapis.com:8000" def test_prediction_service_grpc_transport_channel(): @@ -1245,7 +1236,7 @@ def test_prediction_service_grpc_lro_client(): client = PredictionServiceClient( credentials=credentials.AnonymousCredentials(), transport="grpc", ) - transport = client.transport + transport = client._transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsClient,) @@ -1258,7 +1249,7 @@ def test_prediction_service_grpc_lro_async_client(): client = PredictionServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", ) - transport = client.transport + transport = client._client._transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,) @@ -1267,132 +1258,6 @@ def test_prediction_service_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client -def test_model_path(): - project = "squid" - location = "clam" - model = "whelk" - - expected = "projects/{project}/locations/{location}/models/{model}".format( - project=project, location=location, model=model, - ) - actual = PredictionServiceClient.model_path(project, location, model) - assert expected == actual - - -def test_parse_model_path(): - expected = { - "project": "octopus", - "location": "oyster", - "model": "nudibranch", - } - path = PredictionServiceClient.model_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_model_path(path) - assert expected == actual - - -def test_common_billing_account_path(): - billing_account = "cuttlefish" - - expected = "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - actual = PredictionServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "mussel", - } - path = PredictionServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_billing_account_path(path) - assert expected == actual - - -def test_common_folder_path(): - folder = "winkle" - - expected = "folders/{folder}".format(folder=folder,) - actual = PredictionServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "nautilus", - } - path = PredictionServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_folder_path(path) - assert expected == actual - - -def test_common_organization_path(): - organization = "scallop" - - expected = "organizations/{organization}".format(organization=organization,) - actual = PredictionServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "abalone", - } - path = PredictionServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_organization_path(path) - assert expected == actual - - -def test_common_project_path(): - project = "squid" - - expected = "projects/{project}".format(project=project,) - actual = PredictionServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "clam", - } - path = PredictionServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_project_path(path) - assert expected == actual - - -def test_common_location_path(): - project = "whelk" - location = "octopus" - - expected = "projects/{project}/locations/{location}".format( - project=project, location=location, - ) - actual = PredictionServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "oyster", - "location": "nudibranch", - } - path = PredictionServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = PredictionServiceClient.parse_common_location_path(path) - assert expected == actual - - def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() From 465e034440fa10416d7f8ba994b78efad04b6da8 Mon Sep 17 00:00:00 2001 From: yoshi-automation Date: Fri, 23 Oct 2020 06:06:54 -0700 Subject: [PATCH 21/25] chore: update grpc dependency to v1.33.1 PiperOrigin-RevId: 338646463 Source-Author: Google APIs Source-Date: Fri Oct 23 03:57:15 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: 20b11dfe4538cd5da7b4c3dd7d2bf5b9922ff3ed Source-Link: https://github.com/googleapis/googleapis/commit/20b11dfe4538cd5da7b4c3dd7d2bf5b9922ff3ed --- .../automl_v1/services/auto_ml/async_client.py | 18 +++++++++--------- .../services/auto_ml/transports/base.py | 18 +++++++++--------- synth.metadata | 4 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/google/cloud/automl_v1/services/auto_ml/async_client.py b/google/cloud/automl_v1/services/auto_ml/async_client.py index a2cc6f22..23d7b118 100644 --- a/google/cloud/automl_v1/services/auto_ml/async_client.py +++ b/google/cloud/automl_v1/services/auto_ml/async_client.py @@ -293,7 +293,7 @@ async def get_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -375,7 +375,7 @@ async def list_datasets( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -563,7 +563,7 @@ async def delete_dataset( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -868,7 +868,7 @@ async def get_annotation_spec( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1041,7 +1041,7 @@ async def get_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1123,7 +1123,7 @@ async def list_models( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1226,7 +1226,7 @@ async def delete_model( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1715,7 +1715,7 @@ async def get_model_evaluation( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -1820,7 +1820,7 @@ async def list_model_evaluations( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, diff --git a/google/cloud/automl_v1/services/auto_ml/transports/base.py b/google/cloud/automl_v1/services/auto_ml/transports/base.py index 7deddee8..b1e12781 100644 --- a/google/cloud/automl_v1/services/auto_ml/transports/base.py +++ b/google/cloud/automl_v1/services/auto_ml/transports/base.py @@ -122,7 +122,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -135,7 +135,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -151,7 +151,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -170,7 +170,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -186,7 +186,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -199,7 +199,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -212,7 +212,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -237,7 +237,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, @@ -250,7 +250,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, ), ), default_timeout=5.0, diff --git a/synth.metadata b/synth.metadata index 35ddbf7c..fe27c523 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,8 +11,8 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "4b34a0869404af9d83ae89952d28712a4d29eba6", - "internalRef": "338489505" + "sha": "20b11dfe4538cd5da7b4c3dd7d2bf5b9922ff3ed", + "internalRef": "338646463" } }, { From 63e814f5e547576f83318ee36daf466292982b7c Mon Sep 17 00:00:00 2001 From: Bu Sun Kim Date: Tue, 27 Oct 2020 00:18:27 +0000 Subject: [PATCH 22/25] chore: update proto-plus, undo docs removal --- docs/automl_v1beta1/services.rst | 3 +++ setup.py | 2 +- synth.py | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/automl_v1beta1/services.rst b/docs/automl_v1beta1/services.rst index 9fa5c54f..511f02ad 100644 --- a/docs/automl_v1beta1/services.rst +++ b/docs/automl_v1beta1/services.rst @@ -7,3 +7,6 @@ Services for Google Cloud Automl v1beta1 API .. automodule:: google.cloud.automl_v1beta1.services.prediction_service :members: :inherited-members: +.. automodule:: google.cloud.automl_v1beta1.services.tables + :members: + :inherited-members: diff --git a/setup.py b/setup.py index d9a7b069..6c0ad166 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ "google-api-core[grpc] >= 1.22.0, < 2.0.0dev", - "proto-plus >= 1.4.0", + "proto-plus >= 1.10.0", "libcst >= 0.2.5", ] extras = { diff --git a/synth.py b/synth.py index 017d2a67..b904e3a0 100644 --- a/synth.py +++ b/synth.py @@ -56,6 +56,15 @@ """__all__ = ("GcsClient", "TablesClient",""" ) +s.replace( + "docs/automl_v1beta1/services.rst", + """(google\.cloud\.automl_v1beta1\.services\.prediction_service + :members: + :inherited-members:)""", + """\g<1>\n.. automodule:: google.cloud.automl_v1beta1.services.tables + :members: + :inherited-members:""" +) # ---------------------------------------------------------------------------- # Add templated files From aabb68b40f61a9616ea18725449c664e60b646fb Mon Sep 17 00:00:00 2001 From: Bu Sun Kim Date: Tue, 27 Oct 2020 00:21:17 +0000 Subject: [PATCH 23/25] fix: fix imports --- google/cloud/automl_v1beta1/__init__.py | 4 ++-- synth.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 30db2703..1362287d 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -17,8 +17,8 @@ from .services.auto_ml import AutoMlClient from .services.prediction_service import PredictionServiceClient -from .tables.gcs_client import GcsClient -from .tables.tables_client import TablesClient +from .services.gcs_client import GcsClient +from .services.tables_client import TablesClient from .types.annotation_payload import AnnotationPayload from .types.annotation_spec import AnnotationSpec from .types.classification import ClassificationAnnotation diff --git a/synth.py b/synth.py index b904e3a0..73c0253d 100644 --- a/synth.py +++ b/synth.py @@ -46,8 +46,8 @@ from \.services\.prediction_service import PredictionServiceClient""", """from .services.auto_ml import AutoMlClient from .services.prediction_service import PredictionServiceClient -from .tables.gcs_client import GcsClient -from .tables.tables_client import TablesClient""" +from .services.gcs_client import GcsClient +from .services.tables_client import TablesClient""" ) s.replace( From 31da1a937751d08e1d569fa06731b6943d51ff35 Mon Sep 17 00:00:00 2001 From: Bu Sun Kim Date: Tue, 27 Oct 2020 00:27:54 +0000 Subject: [PATCH 24/25] fix: fix __init__.py again --- google/cloud/automl_v1beta1/__init__.py | 4 ++-- synth.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 1362287d..30db2703 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -17,8 +17,8 @@ from .services.auto_ml import AutoMlClient from .services.prediction_service import PredictionServiceClient -from .services.gcs_client import GcsClient -from .services.tables_client import TablesClient +from .tables.gcs_client import GcsClient +from .tables.tables_client import TablesClient from .types.annotation_payload import AnnotationPayload from .types.annotation_spec import AnnotationSpec from .types.classification import ClassificationAnnotation diff --git a/synth.py b/synth.py index 73c0253d..b904e3a0 100644 --- a/synth.py +++ b/synth.py @@ -46,8 +46,8 @@ from \.services\.prediction_service import PredictionServiceClient""", """from .services.auto_ml import AutoMlClient from .services.prediction_service import PredictionServiceClient -from .services.gcs_client import GcsClient -from .services.tables_client import TablesClient""" +from .tables.gcs_client import GcsClient +from .tables.tables_client import TablesClient""" ) s.replace( From d348416ca99cf52fcf80e86804565b5e42341e8e Mon Sep 17 00:00:00 2001 From: Bu Sun Kim Date: Tue, 27 Oct 2020 00:36:20 +0000 Subject: [PATCH 25/25] fix: fix for real --- google/cloud/automl_v1beta1/__init__.py | 4 ++-- synth.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/google/cloud/automl_v1beta1/__init__.py b/google/cloud/automl_v1beta1/__init__.py index 30db2703..904a45aa 100644 --- a/google/cloud/automl_v1beta1/__init__.py +++ b/google/cloud/automl_v1beta1/__init__.py @@ -17,8 +17,8 @@ from .services.auto_ml import AutoMlClient from .services.prediction_service import PredictionServiceClient -from .tables.gcs_client import GcsClient -from .tables.tables_client import TablesClient +from .services.tables.gcs_client import GcsClient +from .services.tables.tables_client import TablesClient from .types.annotation_payload import AnnotationPayload from .types.annotation_spec import AnnotationSpec from .types.classification import ClassificationAnnotation diff --git a/synth.py b/synth.py index b904e3a0..638228ec 100644 --- a/synth.py +++ b/synth.py @@ -46,8 +46,8 @@ from \.services\.prediction_service import PredictionServiceClient""", """from .services.auto_ml import AutoMlClient from .services.prediction_service import PredictionServiceClient -from .tables.gcs_client import GcsClient -from .tables.tables_client import TablesClient""" +from .services.tables.gcs_client import GcsClient +from .services.tables.tables_client import TablesClient""" ) s.replace(