Skip to content
This repository was archived by the owner on Mar 2, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions google/cloud/firestore_v1/base_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,15 @@ def find_nearest(
stages.FindNearest(field, vector, distance_measure, options)
)

def literals(
self,
documents: Selectable,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The type hint for documents is Selectable, but the implementation in Literals.__init__ also handles str. To be consistent with the implementation and other methods in this class (like select), the type hint should be str | Selectable.

Suggested change
documents: Selectable,
documents: str | Selectable,

) -> "_BasePipeline":
"""
TODO: add docstring.
"""
Comment on lines +277 to +338
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The docstring for the literals method is a TODO placeholder. Please add a complete docstring explaining what the method does, its parameters, and providing examples of its usage. This is important for maintainability and for other developers to understand how to use this new pipeline stage.

        """Starts a pipeline with a fixed set of documents.

        This stage replaces the current set of documents in the pipeline with a
        new set of literal documents. This is useful for testing or for pipelines
        that operate on a predefined set of data.

        The documents can be provided directly as a `Constant` expression or
        indirectly via a field reference from the input documents.

        Example (with a `Constant`):
            >>> from google.cloud.firestore_v1.pipeline_expressions import Constant
            >>>
            >>> documents = [
            ...     {"name": "Alice", "score": 95},
            ...     {"name": "Bob", "score": 87},
            ... ]
            >>> pipeline = client.pipeline().literals(Constant.of(documents))

        Example (with a field reference):
            >>> # Assumes input documents have a field 'document_list' containing an array of documents.
            >>> pipeline = client.pipeline().collection("sources").literals("document_list")

        Args:
            documents: A `str` or `Selectable` expression. If a `str`, it's
                       treated as a field path to an array of documents.
                       If a `Selectable`, it's usually a `Constant`
                       containing an array of documents (as dictionaries).

        Returns:
            A new Pipeline object with this stage appended to the stage list.
        """

return self._append(stages.Literals(documents))

def replace_with(
self,
field: Selectable,
Expand Down
11 changes: 11 additions & 0 deletions google/cloud/firestore_v1/pipeline_stages.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,17 @@ def _pb_args(self):
return [Value(integer_value=self.limit)]


class Literals(Stage):
"""TODO: add docstring."""
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The docstring for the Literals class is a TODO placeholder. Please add a docstring explaining what the stage does.

Suggested change
"""TODO: add docstring."""
"""Starts a pipeline with a fixed set of documents."""


def __init__(self, documents: Selectable):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The type hint for documents is Selectable, but the implementation in __init__ also handles str. To be consistent with the implementation, the type hint should be str | Selectable.

Suggested change
def __init__(self, documents: Selectable):
def __init__(self, documents: str | Selectable):

super().__init__("literals")
self.documents = Field(documents) if isinstance(documents, str) else documents

def _pb_args(self):
return [self.documents._to_pb()]


class Offset(Stage):
"""Skips a specified number of documents."""

Expand Down
25 changes: 24 additions & 1 deletion tests/system/pipeline_e2e/general.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -684,4 +684,27 @@ tests:
- args:
- fieldReferenceValue: awards
- stringValue: full_replace
name: replace_with
name: replace_with
- description: literals
pipeline:
- Literals:
- Constant:
- title: "The Hitchhiker's Guide to the Galaxy"
author: "Douglas Adams"
assert_results:
- title: "The Hitchhiker's Guide to the Galaxy"
author: "Douglas Adams"
assert_proto:
pipeline:
stages:
- args:
- arrayValue:
values:
- mapValue:
fields:
author:
stringValue: "Douglas Adams"
title:
stringValue: "The Hitchhiker's Guide to the Galaxy"
name: literals

1 change: 1 addition & 0 deletions tests/unit/v1/test_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ def test_pipeline_execute_stream_equivalence():
),
("replace_with", ("name",), stages.ReplaceWith),
("replace_with", (Field.of("n"),), stages.ReplaceWith),
("literals", (Field.of("a"),), stages.Literals),
("sort", (Field.of("n").descending(),), stages.Sort),
("sort", (Field.of("n").descending(), Field.of("m").ascending()), stages.Sort),
("sample", (10,), stages.Sample),
Expand Down
26 changes: 26 additions & 0 deletions tests/unit/v1/test_pipeline_stages.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,32 @@ def test_to_pb(self):
assert len(result.options) == 0


class TestLiterals:
def _make_one(self, *args, **kwargs):
return stages.Literals(*args, **kwargs)

def test_ctor(self):
val = Constant.of({"a": 1})
instance = self._make_one(val)
assert instance.documents == val
assert instance.name == "literals"

def test_repr(self):
val = Constant.of({"a": 1})
instance = self._make_one(val)
repr_str = repr(instance)
assert repr_str == "Literals(documents=Constant.of({'a': 1}))"

def test_to_pb(self):
val = Constant.of({"a": 1})
instance = self._make_one(val)
result = instance._to_pb()
assert result.name == "literals"
assert len(result.args) == 1
assert result.args[0].map_value.fields["a"].integer_value == 1
assert len(result.options) == 0


class TestOffset:
def _make_one(self, *args, **kwargs):
return stages.Offset(*args, **kwargs)
Expand Down
Loading