kiarina-lib-firebase-rtdb
Dependencies
| Package | Version | License |
|---|---|---|
| HTTPX | >=0.28.1 |
BSD-3-Clause |
| kiarina-lib-firebase | >=2.27.0 |
MIT |
| Pydantic | >=2.10.6 |
MIT |
| Pydantic Settings | >=2.10.1 |
MIT |
| pydantic-settings-manager | >=3.2.0 |
MIT |
Installation
pip install kiarina-lib-firebase-rtdb
Features
- Retrieving Data Retrieves data at a path through the Firebase Realtime Database REST API.
- Querying Data
Orders, limits and ranges the result with
RTDBQuery, which encodes the REST query parameters. - Updating Data
Writes a multi-path update, and deletes keys by sending
None. - Watching Data Changes Yields the current value of a path each time it changes, kept in sync from the Server-Sent Events stream.
- Reading Your Own Writes
Shares an
RTDBMirrorbetweenwatch_dataandupdate_data, so a successful update is visible locally before the stream echoes it back. - Recovering the Stream Refreshes the ID token after authentication revocation and reconnects with exponential backoff after network errors and token refresh failures.
- Stopping the Stream
Stops a watch with an
asyncio.Event. - Resolving the Token
Passes a token explicitly, or uses the token manager of the named
kiarina.lib.firebasesettings. - Configuring Retries Configures retry intervals through environment variables or pydantic-settings-manager.
Retrieving Data
Get a token from a TokenManager and specify a database path. create_token_manager reads the API key and the token file from the kiarina.lib.firebase settings.
from kiarina.lib.firebase import create_token_manager
from kiarina.lib.firebase_rtdb import get_data
token_manager = create_token_manager()
data = await get_data(
"https://your-project-default-rtdb.firebaseio.com",
"/agents/state",
token=await token_manager.get_token(),
)
Querying Data
RTDBQuery builds the REST query parameters and JSON-encodes their values, which the REST API requires. Ordering by $key needs no index and is chronological when keys are ULIDs.
from kiarina.lib.firebase_rtdb import RTDBQuery, get_data
data = await get_data(
"https://your-project-default-rtdb.firebaseio.com",
"/agents/messages",
query=RTDBQuery(order_by="$key", limit_to_last=5),
token=await token_manager.get_token(),
)
Pass start_after to fetch only the entries added after the last key already seen.
query = RTDBQuery(order_by="$key", start_after="01ABCDEF...")
shallow truncates every value to true and returns the keys alone. The REST API rejects it together with any other parameter, so RTDBQuery raises a validation error for that combination.
keys = await get_data(
"https://your-project-default-rtdb.firebaseio.com",
"/agents/messages",
query=RTDBQuery(shallow=True),
token=await token_manager.get_token(),
)
Updating Data
update_data sends a multi-path update. Keys are paths relative to the given path, and a None value deletes the key.
from kiarina.lib.firebase_rtdb import update_data
await update_data(
"https://your-project-default-rtdb.firebaseio.com",
"/agents/messages",
{"01ABCDEF.../read": True, "01OLDEST...": None},
token=await token_manager.get_token(),
)
Watching Data Changes
watch_data yields the whole value at the path, in the same shape get_data returns, each time it changes. It applies the stream's put and patch events to a local copy, so deletions are reflected too: a removed child disappears from the next value, and the value is None while the path does not exist.
from kiarina.lib.firebase_rtdb import watch_data
async for entries in watch_data(
"https://your-project-default-rtdb.firebaseio.com",
"/agents/entries",
token_manager=token_manager,
):
unread = [key for key, entry in (entries or {}).items() if not entry.get("read")]
The first value arrives once Firebase sends the initial snapshot. A value equal to the previous one is not yielded again. Each yielded value is an independent copy, so the caller may modify it.
Reading Your Own Writes
Pass the same RTDBMirror to watch_data and update_data. watch_data binds the mirror to the watched path and keeps it in sync. update_data applies a successful update to it immediately, so mirror.value reflects the write before the stream echoes it back. The echo then changes nothing, so watch_data does not yield it again.
from kiarina.lib.firebase_rtdb import RTDBMirror, update_data, watch_data
mirror = RTDBMirror()
async for entries in watch_data(DATABASE_URL, "/agents/entries", mirror=mirror):
...
# Elsewhere, while the watch runs
await update_data(DATABASE_URL, "/agents/entries", {"01ABC/read": True}, mirror=mirror)
entries = mirror.value # already has read=True
Only the part of an update under the mirrored path is applied. An update before the first snapshot is not applied, because the snapshot replaces the value anyway.
Recovering the Stream
When authentication is revoked, it calls TokenManager.refresh() and reconnects. An ID token lives for one hour, so this reconnect happens periodically for as long as the watch runs. Right after a reconnect Firebase sends the whole path again, so changes made while disconnected are reflected in the next value.
Network errors and transient token refresh failures use the configured exponential backoff. Errors that retrying cannot recover from, such as an invalidated refresh token, are propagated to the caller.
Stopping the Stream
Setting stop_event ends the watch when the stream next receives data. Cancel the watch task when an immediate stop is required.
import asyncio
from kiarina.lib.firebase_rtdb import watch_data
stop_event = asyncio.Event()
async for value in watch_data(
"https://your-project-default-rtdb.firebaseio.com",
"/agents/state",
stop_event=stop_event,
token_manager=token_manager,
):
print(value)
if value == "stop":
stop_event.set()
Resolving the Token
Omitting token and token_manager uses the TokenManager of the kiarina.lib.firebase settings named by firebase_settings_key.
kiarina.lib.firebase:
configs:
production:
api_key: production-api-key
token_file_path: ~/.config/your-app/token.json
kiarina.lib.firebase_rtdb:
firebase_settings_key: production
data = await get_data(
"https://your-project-default-rtdb.firebaseio.com",
"/agents/state",
)
token_manager_registry builds the token manager from those settings. Register an instance under the same key to use a different TokenStore.
Omitting firebase_settings_key uses the default of token_manager_registry, which is the kiarina.lib.firebase settings that its settings_manager resolves.
Configuring Retries
Retry settings use a single-mode settings_manager.
kiarina.lib.firebase_rtdb:
max_retry_delay: 60.0
initial_retry_delay: 1.0
retry_delay_multiplier: 2.0
Load the settings when the application starts.
import yaml
from pydantic_settings_manager import load_user_configs
from kiarina.lib.firebase_rtdb import settings_manager
with open("config.yaml", encoding="utf-8") as file:
load_user_configs(yaml.safe_load(file) or {})
settings = settings_manager.get_settings()
To configure only this package, assign the values directly to settings_manager.user_config.
from kiarina.lib.firebase_rtdb import settings_manager
settings_manager.user_config = {
"max_retry_delay": 60.0,
"initial_retry_delay": 1.0,
"retry_delay_multiplier": 2.0,
}
The same values are available as environment variables.
export KIARINA_LIB_FIREBASE_RTDB_MAX_RETRY_DELAY=60.0
export KIARINA_LIB_FIREBASE_RTDB_INITIAL_RETRY_DELAY=1.0
export KIARINA_LIB_FIREBASE_RTDB_RETRY_DELAY_MULTIPLIER=2.0
API Reference
kiarina.lib.firebase_rtdb
from kiarina.lib.firebase_rtdb import (
RTDBMirror,
RTDBQuery,
RTDBSettings,
RTDBStreamCancelledError,
get_data,
settings_manager,
update_data,
watch_data,
)
get_data
async def get_data(
database_url: str,
path: str,
*,
query: RTDBQuery | None = None,
token: Token | None = None,
) -> Any: ...
Retrieves JSON data at the specified path.
Parameters
database_url(str): Firebase Realtime Database URLpath(str): Path of the data to retrievequery(RTDBQuery | None): Query parameters appended to the requesttoken(Token | None): Firebase token set. Resolved fromtoken_manager_registrywhen omitted
Returns
Any: JSON value from the response
Raises
ValueError: The token is omitted andtoken_manager_registrycannot resolve aTokenManagerhttpx.HTTPStatusError: The HTTP response indicates an error. Its message,request, andresponseomit theauthquery parameter that carries the ID tokenhttpx.HTTPError: The request fails
update_data
async def update_data(
database_url: str,
path: str,
values: Mapping[str, Any],
*,
token: Token | None = None,
mirror: RTDBMirror | None = None,
) -> Any: ...
Applies a multi-path update at the specified path.
Parameters
database_url(str): Firebase Realtime Database URLpath(str): Path the update is applied tovalues(Mapping[str, Any]): Keys relative topathand their new values.Nonedeletes the keytoken(Token | None): Firebase token set. Resolved fromtoken_manager_registrywhen omittedmirror(RTDBMirror | None): Mirror to apply the update to after it succeeds. Only the part under the mirrored path is applied
Returns
Any: JSON value from the response
Raises
ValueError: The token is omitted andtoken_manager_registrycannot resolve aTokenManagerhttpx.HTTPStatusError: The HTTP response indicates an error. Its message,request, andresponseomit theauthquery parameter that carries the ID tokenhttpx.HTTPError: The request fails
watch_data
async def watch_data(
database_url: str,
path: str,
*,
stop_event: asyncio.Event | None = None,
token_manager: TokenManager | None = None,
mirror: RTDBMirror | None = None,
) -> AsyncIterator[Any]: ...
Watches the specified path and yields its whole value each time it changes, kept in sync from the Firebase SSE stream.
Parameters
database_url(str): Firebase Realtime Database URLpath(str): Path of the data to watchstop_event(asyncio.Event | None): Event that requests the watch to stoptoken_manager(TokenManager | None): Instance that manages the token set. Resolved fromtoken_manager_registrywhen omittedmirror(RTDBMirror | None): Mirror to keep in sync with the stream. A new one is used when omitted
Yields
Any: The value at the path, in the same shapeget_datareturns, orNonewhen the path does not exist. The first value is yielded after the initial snapshot arrives, a value equal to the previous one is skipped, and each value is an independent copy
Raises
ValueError: The token is omitted andtoken_manager_registrycannot resolve aTokenManager, ormirroris already bound to another pathRTDBStreamCancelledError: Firebase cancels the streamInvalidRefreshTokenError: The refresh token is no longer usableFirebaseAPIError: Token refresh fails with an error that retrying cannot recover from
Network errors, HTTP error responses, and transient token refresh failures are retried internally. HTTP error responses are logged without the ID token. Other unexpected exceptions are propagated to the caller.
RTDBMirror
class RTDBMirror:
def __init__(self) -> None: ...
@property
def value(self) -> Any: ...
A local copy of one Firebase Realtime Database path. watch_data binds it to the watched path and keeps it in sync, and update_data applies successful updates to it.
Properties
value(Any): The current value, orNonebefore the first snapshot and while the path does not exist. Each access returns an independent copy
RTDBQuery
class RTDBQuery(BaseModel):
order_by: str | None = None
limit_to_first: int | None = None
limit_to_last: int | None = None
start_at: QueryValue | None = None
start_after: QueryValue | None = None
end_at: QueryValue | None = None
end_before: QueryValue | None = None
equal_to: QueryValue | None = None
shallow: bool = False
Query parameters for the Firebase Realtime Database REST API. QueryValue is str | bool | int | float.
Fields
order_by(str | None): Child key to order by, or"$key","$value"or"$priority"limit_to_first(int | None): Number of items to take from the beginning of the ordered resultlimit_to_last(int | None): Number of items to take from the end of the ordered resultstart_at(QueryValue | None): Inclusive lower bound of the ordered resultstart_after(QueryValue | None): Exclusive lower bound of the ordered resultend_at(QueryValue | None): Inclusive upper bound of the ordered resultend_before(QueryValue | None): Exclusive upper bound of the ordered resultequal_to(QueryValue | None): Exact value the ordered child must matchshallow(bool): Truncate each value totrue
Methods
to_params() -> dict[str, str]: Returns the REST query parameters with JSON-encoded values
Raises
ValidationError:shallowis combined with another parameter, a filter is used withoutorder_by, or mutually exclusive parameters are set together
RTDBSettings
class RTDBSettings(BaseSettings):
firebase_settings_key: str | None = None
max_retry_delay: float = 60.0
initial_retry_delay: float = 1.0
retry_delay_multiplier: float = 2.0
Settings used when resolving the token and reconnecting a stream.
Fields
firebase_settings_key(str | None): Key of thekiarina.lib.firebasesettings whoseTokenManageris used when no token is passed. An alias ofkiarina.lib.firebaseis also accepted. The default oftoken_manager_registryis used when this is not setmax_retry_delay(float): Maximum retry interval in secondsinitial_retry_delay(float): Initial retry interval in secondsretry_delay_multiplier(float): Value multiplied by the retry interval after a network error
settings_manager
settings_manager: SettingsManager[RTDBSettings]
Manages a single RTDBSettings configuration.
RTDBStreamCancelledError
class RTDBStreamCancelledError(Exception): ...
Indicates that Firebase cancelled the SSE stream.
Metadata
Release files for kiarina-lib-firebase-rtdb 2.30.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| kiarina_lib_firebase_rtdb-2.30.0.tar.gz | 22.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kiarina_lib_firebase_rtdb-2.30.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 39.0 kB
Release files / kiarina_lib_firebase_rtdb-2.30.0.tar.gz
| Download URL | kiarina_lib_firebase_rtdb-2.30.0.tar.gz |
|---|---|
| Size | 22.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7dcff4c4320c38fdcd5dfc15f53953500a03fafb287b0a1cb9bac901624b38d0
|
|
BLAKE2b-256 checksum How to use checksums |
60ac99fcf78a5bbc8fc407d3d3a72f4de738687d986bdc2c3cbb6a4c30d98f8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 14, 2026.
Transparency logRelease files / kiarina_lib_firebase_rtdb-2.30.0-py3-none-any.whl
| Download URL | kiarina_lib_firebase_rtdb-2.30.0-py3-none-any.whl |
|---|---|
| Size | 16.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4d8e99c0622bb0d6b059a1e8b18326ceaf96406db530c182a4d2aec0193dbbb2
|
|
BLAKE2b-256 checksum How to use checksums |
26eef1d82fa01feaabb154d42e3a55a2ca746709d84876d552f47d7b1bf36c7b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 14, 2026.
Transparency log