Skip to main content

Examples & Cookbook

Real-world code examples, recipes for common use cases, and production-ready patterns for using the Taruvi SDK effectively.


Database Examples

Complex Query with Multiple Filters

# Search for active adult users created this year
from datetime import datetime

year_start = datetime.now().replace(month=1, day=1).isoformat()

users = (
auth_client.database.query("users")
.filter("is_active", "eq", True)
.filter("age", "gte", 18)
.filter("created_at", "gte", year_start)
.sort("created_at", "desc")
.page_size(50)
.get()
)

print(f"Found {len(users)} active adult users created this year")

Bulk Create with Error Handling

from taruvi import ValidationError

users_to_create = [
{"username": "user1", "email": "user1@example.com"},
{"username": "user2", "email": "user2@example.com"},
{"username": "user3", "email": "user3@example.com"}
]

try:
new_users = auth_client.database.create("users", users_to_create)
print(f"Created {len(new_users)} users")
except ValidationError as e:
print(f"Validation failed: {e.details}")

Pagination for Large Datasets

# ✅ Good: Paginate large results
for page in range(1, 11):
users = auth_client.database.query("users").page(page).page_size(100).get()
process_users(users)

# ❌ Bad: Load all at once
users = auth_client.database.query("users").get() # Could be 10,000+ records!

Use populate() to Avoid N+1 Queries

# ✅ Good: Eager load relationships
posts = auth_client.database.query("posts").populate("author", "comments").get()

# ❌ Bad: N+1 queries
posts = auth_client.database.query("posts").get()
for post in posts:
author = auth_client.database.get("users", post['author_id']) # Extra query!

Function Examples

Execute Function with Polling

import time

# Execute async
result = auth_client.functions.execute(
"process-large-dataset",
params={"dataset_id": 123},
is_async=True
)

task_id = result['invocation']['celery_task_id']

# Poll for result
while True:
task_result = auth_client.functions.get_result(task_id)
status = task_result['data']['status']

if status == 'SUCCESS':
print(f"Success: {task_result['data']['result']}")
break
elif status == 'FAILURE':
print(f"Failed: {task_result['data']['error']}")
break

print("Still processing...")
time.sleep(2)

Storage Examples

Upload and Process Image

# Upload image
with open("profile.jpg", "rb") as f:
result = auth_client.storage.from_("images").upload(
files=[("profile.jpg", f)],
paths=["users/123/profile.jpg"],
metadatas=[{"type": "profile_photo"}]
)

file_path = result[0]['path']
print(f"Uploaded: {file_path}")

# Process with function
process_result = auth_client.functions.execute(
"resize-image",
params={"path": file_path, "width": 200, "height": 200}
)

print(f"Processed: {process_result['data']}")

Integration Examples

FastAPI Integration

from fastapi import FastAPI, Depends, HTTPException
from taruvi import Client, NotFoundError

app = FastAPI()

def get_client():
client = Client(api_url="...", app_slug="...")
return client.auth.signInWithToken(
token="api-key",
token_type="api_key"
)

@app.get("/users/{user_id}")
async def get_user(user_id: int, client = Depends(get_client)):
try:
user = client.database.get("users", record_id=user_id)
return user
except NotFoundError:
raise HTTPException(status_code=404, detail="User not found")

Security Best Practices

Never Hardcode Credentials

# ❌ Bad: Hardcoded credentials
client = Client(
api_url="https://api.taruvi.cloud",
app_slug="my-app"
)
auth_client = client.auth.signInWithPassword(
username="alice@example.com",
password="supersecret123"
)

# ✅ Good: Environment variables
import os
from dotenv import load_dotenv

load_dotenv()
client = Client(
api_url=os.getenv("TARUVI_API_URL"),
app_slug=os.getenv("TARUVI_APP_SLUG")
)
auth_client = client.auth.signInWithPassword(
username=os.getenv("TARUVI_USERNAME"),
password=os.getenv("TARUVI_PASSWORD")
)

Use API Keys for Machine-to-Machine

# ✅ Good: API key for background jobs
auth_client = client.auth.signInWithToken(
token=os.getenv("TARUVI_API_KEY"),
token_type="api_key"
)
Token Rotation

Rotate API keys and tokens regularly, especially after team member changes.


Performance Best Practices

Reuse Clients

# ✅ Good: Create client once
client = Client(api_url="...", app_slug="...")
auth_client = client.auth.signInWithPassword(username="...", password="...")

# Use throughout application
users = auth_client.database.query("users").get()
result = auth_client.functions.execute("my-function")

# ❌ Bad: Create new client for each operation
client1 = Client(api_url="...", app_slug="...")
auth1 = client1.auth.signInWithPassword(username="...", password="...")
users = auth1.database.query("users").get()

client2 = Client(api_url="...", app_slug="...")
auth2 = client2.auth.signInWithPassword(username="...", password="...")
result = auth2.functions.execute("my-function")

Use Async for Concurrent Operations

# ✅ Good: Concurrent async
import asyncio

client = Client(mode='async', api_url="...", app_slug="...")
auth_client = client.auth.signInWithPassword(username="...", password="...")

users, posts, comments = await asyncio.gather(
auth_client.database.query("users").get(),
auth_client.database.query("posts").get(),
auth_client.database.query("comments").get()
)

# ❌ Bad: Sequential sync
users = auth_client.database.query("users").get()
posts = auth_client.database.query("posts").get()
comments = auth_client.database.query("comments").get()

Error Handling Patterns

Catch Specific Exceptions

from taruvi import NotFoundError, ValidationError, TaruviError

# ✅ Good: Specific exception handling
try:
user = auth_client.database.get("users", record_id=999)
except NotFoundError:
return {"error": "User not found"}, 404
except ValidationError as e:
return {"error": e.message, "details": e.details}, 400
except TaruviError as e:
return {"error": "Internal error"}, 500

# ❌ Bad: Generic exception
try:
user = auth_client.database.get("users", record_id=999)
except Exception as e:
return {"error": str(e)}, 500 # Exposes internal details!

Implement Retry Logic

# ✅ Good: Retry with backoff
import time
from taruvi import ServerError

def with_retry(func, max_attempts=3):
for attempt in range(max_attempts):
try:
return func()
except ServerError:
if attempt == max_attempts - 1:
raise
time.sleep(2 ** attempt)

users = with_retry(lambda: auth_client.database.query("users").get())

Code Organization

Use Dependency Injection

# ✅ Good: Dependency injection
class UserService:
def __init__(self, client):
self.client = client

def get_active_users(self):
return self.client.database.query("users").filter("is_active", "eq", True).get()

# Easy to test with mock client
service = UserService(auth_client)
users = service.get_active_users()

Create Service Classes

# ✅ Good: Organized service classes
class DatabaseService:
def __init__(self, client):
self.client = client

def get_user(self, user_id):
return self.client.database.get("users", record_id=user_id)

def create_user(self, data):
return self.client.database.create("users", data)

class FunctionService:
def __init__(self, client):
self.client = client

def send_email(self, to, subject, body):
return self.client.functions.execute("send-email", params={
"to": to,
"subject": subject,
"body": body
})

Testing

Mock SDK Calls

from unittest.mock import Mock, patch

def test_get_users():
# Mock the database query
mock_client = Mock()
mock_client.database.query.return_value.get.return_value = [
{"id": 1, "username": "alice"},
{"id": 2, "username": "bob"}
]

service = UserService(mock_client)
users = service.get_active_users()

assert len(users) == 2
assert users[0]["username"] == "alice"