Source code for bigframes.extensions.core.series_accessor

# Copyright 2026 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.
#
# DO NOT MODIFY THIS FILE DIRECTLY.
# This file was generated by the script: scripts/generate_bigframes_bigquery.py
#

from __future__ import annotations

import abc
from typing import (
    Any,
    Generic,
    Literal,
    Optional,
    TypeVar,
    Union,
    cast,
)

import bigframes.core.col
import bigframes.core.sentinels as sentinels
import bigframes.series as series
import bigframes.session

S = TypeVar("S")


class AbstractBigQuerySeriesAccessor(abc.ABC, Generic[S]):
    def __init__(self, obj: S):
        self._obj = obj

    @abc.abstractmethod
    def _bf_from_series(
        self, session: Optional[bigframes.session.Session] = None
    ) -> series.Series:
        """Convert the accessor's object to a BigFrames Series."""

    @abc.abstractmethod
    def _to_series(self, bf_series: series.Series) -> S:
        """Convert a BigFrames Series to the accessor's object type."""


[docs] class BigQuerySeriesAccessor(AbstractBigQuerySeriesAccessor[S]): """Series accessor for BigQuery functions.""" @property @abc.abstractmethod def aead(self) -> AeadSeriesAccessor[S]: """Accessor for BigQuery aead functions."""
[docs] def deterministic_decrypt_bytes( self, ciphertext: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], ], additional_data: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], ], *, session: Optional[bigframes.session.Session] = None, ) -> S: """Uses the matching key from `keyset` to decrypt `ciphertext` and verifies the integrity of the data using `additional_data`. Returns an error if decryption fails.""" from bigframes.operations.googlesql.global_namespace.aead_encryption import ( deterministic_decrypt_bytes as deterministic_decrypt_bytes_impl, ) # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( ciphertext, additional_data, ) bf_series = self._bf_from_series(session) result = deterministic_decrypt_bytes_impl( bf_series, ciphertext, additional_data, ) return self._to_series(cast(series.Series, result))
[docs] def deterministic_decrypt_string( self, ciphertext: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], ], additional_data: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], ], *, session: Optional[bigframes.session.Session] = None, ) -> S: """Like `DETERMINISTIC_DECRYPT_BYTES`, but where plaintext is of type STRING.""" from bigframes.operations.googlesql.global_namespace.aead_encryption import ( deterministic_decrypt_string as deterministic_decrypt_string_impl, ) # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( ciphertext, additional_data, ) bf_series = self._bf_from_series(session) result = deterministic_decrypt_string_impl( bf_series, ciphertext, additional_data, ) return self._to_series(cast(series.Series, result))
[docs] def deterministic_encrypt( self, plaintext: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], ], additional_data: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], ], *, session: Optional[bigframes.session.Session] = None, ) -> S: """Encrypts `plaintext` using the primary cryptographic key in `keyset` using deterministic AEAD. The algorithm of the primary key must be `DETERMINISTIC_AEAD_AES_SIV_CMAC_256`. Binds the ciphertext to the context defined by `additional_data`. Returns `NULL` if any input is `NULL`.""" from bigframes.operations.googlesql.global_namespace.aead_encryption import ( deterministic_encrypt as deterministic_encrypt_impl, ) # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( plaintext, additional_data, ) bf_series = self._bf_from_series(session) result = deterministic_encrypt_impl( bf_series, plaintext, additional_data, ) return self._to_series(cast(series.Series, result))
[docs] def array_concat( self, array_expression_2: Union[ series.Series, bigframes.core.col.Expression, Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], ], *, session: Optional[bigframes.session.Session] = None, ) -> S: """Concatenates one or more arrays with the same element type into a single array.""" from bigframes.operations.googlesql.global_namespace.array import ( array_concat as array_concat_impl, ) # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( array_expression_2, ) bf_series = self._bf_from_series(session) result = array_concat_impl( bf_series, array_expression_2, ) return self._to_series(cast(series.Series, result))
[docs] def array_first( self, *, session: Optional[bigframes.session.Session] = None, ) -> S: """Takes an array and returns the first element in the array.""" from bigframes.operations.googlesql.global_namespace.array import ( array_first as array_first_impl, ) bf_series = self._bf_from_series(session) result = array_first_impl( bf_series, ) return self._to_series(cast(series.Series, result))
[docs] def array_first_n( self, n: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], ], *, session: Optional[bigframes.session.Session] = None, ) -> S: """Returns a prefix of `input_array` consisting of the first `n` elements.""" from bigframes.operations.googlesql.global_namespace.array import ( array_first_n as array_first_n_impl, ) # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( n, ) bf_series = self._bf_from_series(session) result = array_first_n_impl( bf_series, n, ) return self._to_series(cast(series.Series, result))
[docs] def array_includes( self, search_value: Union[ series.Series, bigframes.core.col.Expression, Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], ], *, session: Optional[bigframes.session.Session] = None, ) -> S: """Takes an array and returns `TRUE` if there is an element in the array that is equal to the search_value.""" from bigframes.operations.googlesql.global_namespace.array import ( array_includes as array_includes_impl, ) # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( search_value, ) bf_series = self._bf_from_series(session) result = array_includes_impl( bf_series, search_value, ) return self._to_series(cast(series.Series, result))
[docs] def array_includes_all( self, search_values: Union[ series.Series, bigframes.core.col.Expression, Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], ], *, session: Optional[bigframes.session.Session] = None, ) -> S: """Takes an array to search and an array of search values. Returns `TRUE` if all search values are in the array to search, otherwise returns `FALSE`.""" from bigframes.operations.googlesql.global_namespace.array import ( array_includes_all as array_includes_all_impl, ) # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( search_values, ) bf_series = self._bf_from_series(session) result = array_includes_all_impl( bf_series, search_values, ) return self._to_series(cast(series.Series, result))
[docs] def array_includes_any( self, search_values: Union[ series.Series, bigframes.core.col.Expression, Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT]], ], *, session: Optional[bigframes.session.Session] = None, ) -> S: """Takes an array to search and an array of search values. Returns `TRUE` if any search values are in the array to search, otherwise returns `FALSE`.""" from bigframes.operations.googlesql.global_namespace.array import ( array_includes_any as array_includes_any_impl, ) # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( search_values, ) bf_series = self._bf_from_series(session) result = array_includes_any_impl( bf_series, search_values, ) return self._to_series(cast(series.Series, result))
[docs] def array_is_distinct( self, *, session: Optional[bigframes.session.Session] = None, ) -> S: """Returns `TRUE` if the array contains no repeated elements, using the same equality comparison logic as `SELECT DISTINCT`.""" from bigframes.operations.googlesql.global_namespace.array import ( array_is_distinct as array_is_distinct_impl, ) bf_series = self._bf_from_series(session) result = array_is_distinct_impl( bf_series, ) return self._to_series(cast(series.Series, result))
[docs] def array_last( self, *, session: Optional[bigframes.session.Session] = None, ) -> S: """Takes an array and returns the last element in the array.""" from bigframes.operations.googlesql.global_namespace.array import ( array_last as array_last_impl, ) bf_series = self._bf_from_series(session) result = array_last_impl( bf_series, ) return self._to_series(cast(series.Series, result))
[docs] def array_length( self, *, session: Optional[bigframes.session.Session] = None, ) -> S: """Compute the length of each array element in the Series. **Examples:** >>> import bigframes.pandas as bpd >>> import bigframes.bigquery as bbq >>> s = bpd.Series([[1, 2, 8, 3], [], [3, 4]]) >>> bbq.array_length(s) 0 4 1 0 2 2 dtype: Int64 You can call this function using the Series `bigquery` accessor. >>> s.bigquery.array_length() 0 4 1 0 2 2 dtype: Int64 You can also use this accessor on a pandas Series after importing bigframes. >>> import bigframes >>> import pandas as pd >>> ps = pd.Series([[1, 2, 8, 3], [], [3, 4]]) >>> ps.bigquery.array_length() 0 4 1 0 2 2 dtype: Int64 You can also apply this function directly to Series using `apply`. >>> s.apply(bbq.array_length, by_row=False) 0 4 1 0 2 2 dtype: Int64 Args: series (bigframes.series.Series): A Series with array columns. Returns: bigframes.series.Series: A Series of integer values indicating the length of each element in the Series. """ from bigframes.operations.googlesql.global_namespace.array import ( array_length as array_length_impl, ) bf_series = self._bf_from_series(session) result = array_length_impl( bf_series, ) return self._to_series(cast(series.Series, result))
[docs] def array_reverse( self, *, session: Optional[bigframes.session.Session] = None, ) -> S: """Returns the input `ARRAY` with elements in reverse order.""" from bigframes.operations.googlesql.global_namespace.array import ( array_reverse as array_reverse_impl, ) bf_series = self._bf_from_series(session) result = array_reverse_impl( bf_series, ) return self._to_series(cast(series.Series, result))
[docs] def array_slice( self, start_offset: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], ], end_offset: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], ], *, session: Optional[bigframes.session.Session] = None, ) -> S: """Returns an array containing zero or more consecutive elements from the input array.""" from bigframes.operations.googlesql.global_namespace.array import ( array_slice as array_slice_impl, ) # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( start_offset, end_offset, ) bf_series = self._bf_from_series(session) result = array_slice_impl( bf_series, start_offset, end_offset, ) return self._to_series(cast(series.Series, result))
[docs] def array_to_string( self, delimiter: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], ], null_text: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], ] = sentinels.Sentinel.ARGUMENT_DEFAULT, *, session: Optional[bigframes.session.Session] = None, ) -> S: """Converts array elements within a Series into delimited strings. **Examples:** >>> import bigframes.pandas as bpd >>> import bigframes.bigquery as bbq >>> s = bpd.Series([["H", "i", "!"], ["Hello", "World"], np.nan, [], ["Hi"]]) >>> bbq.array_to_string(s, delimiter=", ") 0 H, i, ! 1 Hello, World 2 3 4 Hi dtype: string You can call this function using the Series `bigquery` accessor. >>> s.bigquery.array_to_string(delimiter=", ") 0 H, i, ! 1 Hello, World 2 3 4 Hi dtype: string You can also use this accessor on a pandas Series after importing bigframes. >>> import bigframes >>> import pandas as pd >>> ps = pd.Series([["H", "i", "!"], ["Hello", "World"], None, [], ["Hi"]]) >>> ps.bigquery.array_to_string(delimiter=", ") 0 H, i, ! 1 Hello, World 2 3 4 Hi dtype: string Args: series (bigframes.series.Series): A Series containing arrays. delimiter (str): The string used to separate array elements. null_text (str, optional): The string to replace any NULL values in the array with. Returns: bigframes.series.Series: A Series containing delimited strings. """ from bigframes.operations.googlesql.global_namespace.array import ( array_to_string as array_to_string_impl, ) # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( delimiter, null_text, ) bf_series = self._bf_from_series(session) result = array_to_string_impl( bf_series, delimiter, null_text, ) return self._to_series(cast(series.Series, result))
[docs] def flatten( self, depth: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], int], ] = sentinels.Sentinel.ARGUMENT_DEFAULT, *, session: Optional[bigframes.session.Session] = None, ) -> S: """Takes an array of nested data and flattens a specific part of it into a single, flat array with the [array elements field access operator][array-el-field-operator]. Returns `NULL` if the input value is `NULL`.""" from bigframes.operations.googlesql.global_namespace.array import ( flatten as flatten_impl, ) # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( depth, ) bf_series = self._bf_from_series(session) result = flatten_impl( bf_series, depth, ) return self._to_series(cast(series.Series, result))
[docs] class AeadSeriesAccessor(AbstractBigQuerySeriesAccessor[S]): """Series accessor for BigQuery aead functions."""
[docs] def decrypt_bytes( self, ciphertext: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], ], additional_data: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], ], *, session: Optional[bigframes.session.Session] = None, ) -> S: """Uses the matching key from keyset to decrypt ciphertext and verifies the integrity of the data using additional_data. Returns an error if decryption or verification fails.""" from bigframes.operations.googlesql.aead import ( decrypt_bytes as decrypt_bytes_impl, ) # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( ciphertext, additional_data, ) bf_series = self._bf_from_series(session) result = decrypt_bytes_impl( bf_series, ciphertext, additional_data, ) return self._to_series(cast(series.Series, result))
[docs] def decrypt_string( self, ciphertext: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes], ], additional_data: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], ], *, session: Optional[bigframes.session.Session] = None, ) -> S: """Like AEAD.DECRYPT_BYTES, but where additional_data is of type STRING.""" from bigframes.operations.googlesql.aead import ( decrypt_string as decrypt_string_impl, ) # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( ciphertext, additional_data, ) bf_series = self._bf_from_series(session) result = decrypt_string_impl( bf_series, ciphertext, additional_data, ) return self._to_series(cast(series.Series, result))
[docs] def encrypt( self, plaintext: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], ], additional_data: Union[ series.Series, bigframes.core.col.Expression, Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, str], ], *, session: Optional[bigframes.session.Session] = None, ) -> S: """Encrypts plaintext using the primary cryptographic key in keyset. The algorithm of the primary key must be AEAD_AES_GCM_256. Binds the ciphertext to the context defined by additional_data. Returns NULL if any input is NULL.""" from bigframes.operations.googlesql.aead import encrypt as encrypt_impl # Resolve session from other arguments if not passed if session is None: import bigframes.core.googlesql as googlesql session = googlesql._find_session( plaintext, additional_data, ) bf_series = self._bf_from_series(session) result = encrypt_impl( bf_series, plaintext, additional_data, ) return self._to_series(cast(series.Series, result))