diff --git a/.librarian/config.yaml b/.librarian/config.yaml index 4e6a62c4c085..8079bbab054b 100644 --- a/.librarian/config.yaml +++ b/.librarian/config.yaml @@ -24,11 +24,6 @@ libraries: # Allow releases for bigframes once the bug above is fixed. - id: "bigframes" release_blocked: true -# TODO(https://github.com/googleapis/google-cloud-python/issues/16506): -# Allow generation/release for google-cloud-firestore once this bug is fixed. - - id: "google-cloud-firestore" - generate_blocked: true - release_blocked: true # TODO(https://github.com/googleapis/google-cloud-python/issues/16165): # Allow generation for google-cloud-dialogflow once this bug is fixed. - id: "google-cloud-dialogflow" diff --git a/packages/google-cloud-firestore/google/cloud/firestore_v1/base_pipeline.py b/packages/google-cloud-firestore/google/cloud/firestore_v1/base_pipeline.py index e429f03a7200..61834964e461 100644 --- a/packages/google-cloud-firestore/google/cloud/firestore_v1/base_pipeline.py +++ b/packages/google-cloud-firestore/google/cloud/firestore_v1/base_pipeline.py @@ -37,6 +37,7 @@ if TYPE_CHECKING: # pragma: NO COVER from google.cloud.firestore_v1.async_client import AsyncClient from google.cloud.firestore_v1.client import Client + from google.cloud.firestore_v1.types.document import Value _T = TypeVar("_T", bound="_BasePipeline") @@ -517,7 +518,12 @@ def unnest( """ return self._append(stages.Unnest(field, alias, options)) - def raw_stage(self, name: str, *params: Expression) -> "_BasePipeline": + def raw_stage( + self, + name: str, + *params: Expression, + options: dict[str, Expression | Value] | None = None, + ) -> "_BasePipeline": """ Adds a stage to the pipeline by specifying the stage name as an argument. This does not offer any type safety on the stage params and requires the caller to know the order (and optionally names) @@ -535,11 +541,12 @@ def raw_stage(self, name: str, *params: Expression) -> "_BasePipeline": Args: name: The name of the stage. *params: A sequence of `Expression` objects representing the parameters for the stage. + options: An optional dictionary of stage options. Returns: A new Pipeline object with this stage appended to the stage list """ - return self._append(stages.RawStage(name, *params)) + return self._append(stages.RawStage(name, *params, options=options or {})) def offset(self, offset: int) -> "_BasePipeline": """ diff --git a/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_expressions.py b/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_expressions.py index 630258f9cadd..08fef608ecf0 100644 --- a/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_expressions.py +++ b/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_expressions.py @@ -11,11 +11,6 @@ # 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. -""" -.. warning:: - **Preview API**: Firestore Pipelines is currently in preview and is - subject to potential breaking changes in future releases. -""" from __future__ import annotations @@ -193,7 +188,7 @@ class Expression(ABC): """Represents an expression that can be evaluated to a value within the execution of a pipeline. - Expressionessions are the building blocks for creating complex queries and + Expressions are the building blocks for creating complex queries and transformations in Firestore pipelines. They can represent: - **Field references:** Access values from document fields. @@ -963,7 +958,7 @@ def is_absent(self) -> "BooleanExpression": >>> Field.of("email").is_absent() Returns: - A new `BooleanExpressionession` representing the isAbsent operation. + A new `BooleanExpression` representing the isAbsent operation. """ return BooleanExpression("is_absent", [self]) @@ -1857,10 +1852,6 @@ def array_agg(self) -> "Expression": `None`. The order of elements in the output array is not stable and shouldn't be relied upon. - This API is provided as a preview for developers and may change based - on feedback that we receive. Do not use this API in a production - environment. - Example: >>> # Collect all values of field 'color' into an array >>> Field.of("color").array_agg() @@ -1879,10 +1870,6 @@ def array_agg_distinct(self) -> "Expression": `None`. The order of elements in the output array is not stable and shouldn't be relied upon. - This API is provided as a preview for developers and may change based - on feedback that we receive. Do not use this API in a production - environment. - Example: >>> # Collect distinct values of field 'color' into an array >>> Field.of("color").array_agg_distinct() @@ -1897,10 +1884,6 @@ def first(self) -> "Expression": """Creates an aggregation that finds the first value of an expression across multiple stage inputs. - This API is provided as a preview for developers and may change based - on feedback that we receive. Do not use this API in a production - environment. - Example: >>> # Select the first value of field 'color' >>> Field.of("color").first() @@ -1915,10 +1898,6 @@ def last(self) -> "Expression": """Creates an aggregation that finds the last value of an expression across multiple stage inputs. - This API is provided as a preview for developers and may change based - on feedback that we receive. Do not use this API in a production - environment. - Example: >>> # Select the last value of field 'color' >>> Field.of("color").last() diff --git a/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_result.py b/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_result.py index 7bf17bed40e4..e3fd74677a1e 100644 --- a/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_result.py +++ b/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_result.py @@ -11,11 +11,6 @@ # 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. -""" -.. warning:: - **Preview API**: Firestore Pipelines is currently in preview and is - subject to potential breaking changes in future releases. -""" from __future__ import annotations diff --git a/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_source.py b/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_source.py index 80c8ef27a29c..faa0ed4b32bd 100644 --- a/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_source.py +++ b/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_source.py @@ -11,11 +11,6 @@ # 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. -""" -.. warning:: - **Preview API**: Firestore Pipelines is currently in preview and is - subject to potential breaking changes in future releases. -""" from __future__ import annotations diff --git a/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_stages.py b/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_stages.py index 6c5ac68ddf0d..aadfb377034c 100644 --- a/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_stages.py +++ b/packages/google-cloud-firestore/google/cloud/firestore_v1/pipeline_stages.py @@ -11,11 +11,6 @@ # 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. -""" -.. warning:: - **Preview API**: Firestore Pipelines is currently in preview and is - subject to potential breaking changes in future releases. -""" from __future__ import annotations diff --git a/packages/google-cloud-firestore/tests/unit/v1/test_async_pipeline.py b/packages/google-cloud-firestore/tests/unit/v1/test_async_pipeline.py index 402ab42ee732..aef1d0b3c522 100644 --- a/packages/google-cloud-firestore/tests/unit/v1/test_async_pipeline.py +++ b/packages/google-cloud-firestore/tests/unit/v1/test_async_pipeline.py @@ -450,6 +450,20 @@ def test_async_pipeline_aggregate_with_groups(): assert list(result_ppl.stages[0].accumulators) == [Field.of("title")] +def test_async_pipeline_raw_stage_with_options(): + from google.cloud.firestore_v1.base_vector_query import Field + from google.cloud.firestore_v1.pipeline_stages import RawStage + + start_ppl = _make_async_pipeline() + result_ppl = start_ppl.raw_stage( + "stage_name", Field.of("n"), options={"key": "val"} + ) + assert len(start_ppl.stages) == 0 + assert len(result_ppl.stages) == 1 + assert isinstance(result_ppl.stages[0], RawStage) + assert result_ppl.stages[0].options == {"key": "val"} + + def test_async_pipeline_union_relative_error(): start_ppl = _make_async_pipeline(client=mock.Mock()) other_ppl = _make_async_pipeline(client=None) diff --git a/packages/google-cloud-firestore/tests/unit/v1/test_pipeline.py b/packages/google-cloud-firestore/tests/unit/v1/test_pipeline.py index 82d89a12f978..19667e4d3248 100644 --- a/packages/google-cloud-firestore/tests/unit/v1/test_pipeline.py +++ b/packages/google-cloud-firestore/tests/unit/v1/test_pipeline.py @@ -439,6 +439,20 @@ def test_pipeline_aggregate_with_groups(): assert list(result_ppl.stages[0].accumulators) == [Field.of("title")] +def test_pipeline_raw_stage_with_options(): + from google.cloud.firestore_v1.base_vector_query import Field + from google.cloud.firestore_v1.pipeline_stages import RawStage + + start_ppl = _make_pipeline() + result_ppl = start_ppl.raw_stage( + "stage_name", Field.of("n"), options={"key": "val"} + ) + assert len(start_ppl.stages) == 0 + assert len(result_ppl.stages) == 1 + assert isinstance(result_ppl.stages[0], RawStage) + assert result_ppl.stages[0].options == {"key": "val"} + + def test_pipeline_union_relative_error(): start_ppl = _make_pipeline(client=mock.Mock()) other_ppl = _make_pipeline(client=None)