Metadata-Version: 2.4
Name: pyrestore
Version: 1.0.0
Summary: A modern, lightweight Python wrapper and high-level manager for Firebase Auth and Google Cloud Firestore.
Author-email: Douglas Greep <greepdouglas@gmail.com>
Project-URL: Homepage, https://github.com/DGreep/pyrestore
Project-URL: Bug Tracker, https://github.com/DGreep/pyrestore/issues
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: httpx>=0.24.0
Requires-Dist: Pyrebase4>=4.3.0
Dynamic: license-file

# pyrestore

A modern, lightweight, and beginner-friendly Python wrapper for **Firebase Auth** and **Google Cloud Firestore**. 

Powered by `httpx` and `Pyrebase4`, `Pyrestore` provides a familiar Pyrebase-style fluent interface (`.child().child()`) along with high-level manager abstractions to handle authentication, batch operations, retry logic, and complex Firestore queries seamlessly.

---

## Features

- **High-Level Manager (`FirebaseManager`)**: Single unified client for Auth + Database with simple `True`/`False` return values.
- **Fluent Path Chaining (`pyrestore`)**: Pyrebase-like syntax for low-level document and collection manipulation.
- **Automatic Serialization**: Converts standard Python types (`datetime`, `int`, `bool`, `bytes`, lists, maps) to/from Firestore's strict REST format automatically.
- **Advanced Query Engine**: Full support for `.where()`, `.order_by()`, and `.limit()`.
- **Resilient Batch Writes**: Multi-collection batch operations with built-in retry logic and exponential backoff.
- **Field Transforms**: Server-side atomic increments and server timestamps with `FieldValue`.

---

## Installation

```bash
pip install pyrestore


Getting Started
Python Version
pyrestore was written for Python 3 (>=3.8) and will not work with Python 2.

Add pyrestore to your application
For use with high-level user-based authentication and database management (FirebaseManager), create the following configuration:

Python
from pyrestore import FirebaseManager

config = {
    "apiKey": "apiKey",
    "authDomain": "projectId.firebaseapp.com",
    "projectId": "projectId",
    "storageBucket": "projectId.appspot.com"
}

fb = FirebaseManager(config)
Alternatively, if you want direct low-level access to Firestore using pyrestore:

Python
from pyrestore import pyrestore

db = pyrestore("your-project-id")
Authentication
Authentication can be handled automatically via FirebaseManager or synchronized manually with low-level pyrestore calls.

Python
# Log the user in
if fb.login("user@example.com", "Password123!"):
    print("User ID:", fb.user_id)

# Register a new account
success = fb.signup(
    email="user@example.com",
    password="Password123!",
    required_fields=["fname", "lname"],
    fname="Jane",
    lname="Doe"
)
Token expiry & Refreshing
FirebaseManager handles token refreshing under the hood, but you can also manually refresh sessions:

Python
fb.refresh_session(refresh_token)
For low-level calls, update your database client token as needed:

Python
db.auth(user_id_token)
Database
You can build paths to your data by using the child() method.

Python
db.child("users").child("user_123")
Save Data
push
To save data with an auto-generated document ID, use the push() method.

Python
# High-level
fb.push_document("products", {"name": "Wireless Mouse", "price": 29.99})

# Low-level
data = {"name": "Wireless Mouse", "price": 29.99}
db.child("products").push(data)
set
To create or overwrite a specific document, use the set() method.

Python
# High-level
fb.set_document("users", {"name": "Jane Doe", "role": "admin"})

# Low-level
data = {"name": "Jane Doe", "role": "admin"}
db.child("users").child("user_123").set(data)
update
To update specific fields for an existing entry, use the update() method.

Python
# High-level
fb.update_document("users", {"age": 30})

# Low-level
db.child("users").child("user_123").update({"age": 30})
delete
To delete data for an existing entry, use the delete_document() or delete() methods.

Python
# High-level
fb.delete_document("users", "user_123")

# Low-level
db.child("users").child("user_123").delete()
multi-location updates
You can perform multi-location atomic updates using batch_multi_update() or batch_update():

Python
# Single collection / path batch
fb.batch_update("users", role="admin", age=31)

# Multi-collection uniform batch
fb.batch_multi_update(
    "set",
    users={"user_123": {"name": "Alex"}},
    organizations={"org_101": {"name": "Tech Corp"}}
)

# Multi-collection mixed-action batch
fb.batch_multi_update(
    users={
        "user_123": {"_action": "set", "data": {"name": "Sam", "role": "member"}}
    },
    orders={
        "order_456": {"status": "shipped"} # Defaults to "update"
    },
    tokens={
        "token_789": {"_action": "delete"} # Deletes document
    }
)
Retrieve Data
get
To return data from a path, call the get() method.

Python
# High-level (defaults to logged-in user_id)
user_data = fb.get_document("users")

# Low-level single doc or collection fetch
user = db.child("users").child("user_123").get()
all_users = db.child("users").get()
Complex Queries
Queries can be built by chaining multiple query parameters together on pyrestore.

Python
results = (
    db.child("products")
      .where("rating", ">=", 4)
      .order_by("rating", "DESC")
      .limit(5)
      .get()
)
where
Filter data by specific operators (==, !=, <, <=, >, >=, array-contains, in, array-contains-any).

Python
products = db.child("products").where("category", "==", "electronics").get()
order_by
Sort documents by field in ascending or descending order.

Python
products = db.child("products").order_by("price", "ASC").get()
limit
Limits the number of returned documents.

Python
top_products = db.child("products").order_by("rating", "DESC").limit(10).get()
Helper Methods & Transforms
FieldValue (Atomic Operations)
Perform atomic server-side transformations:

Python
from pyrestore import FieldValue

db.child("products").child("product_123").update({
    "view_count": FieldValue.increment(1),
    "updatedAt": FieldValue.server_timestamp()
})

License
This project is licensed under the MIT License.
