Python SDK

Python SDK Quick Start — WoWSQL Docs

Python Quick Start

WoWSQL Python SDK — Get started in minutes

Get your API key: Use the WoWSQL project dashboard to create or copy your API key. The same key works for database, auth, and storage (unified API key).

Installation

Official package: View on PyPI →

pip install wowsql

Initialize Client

from wowsql import WowSQLClient

# Initialize client with your API key
# Note: The same key works for database, auth, and storage operations
client = WowSQLClient(
    project_url="myproject",  # Your project subdomain
    api_key="your_api_key_here"  # Single key for all operations
)

# Or with full URL
client = WowSQLClient(
    project_url="https://myproject.wowsql.com",
    api_key="your_api_key"
)

# Using context manager (recommended)
with WowSQLClient(project_url="myproject", api_key="key") as client:
    # CORRECT: Always use .select() before .get() or .execute()
    users = client.table("users").select("*").get()

Query Data

Basic Queries

# Get all records - CORRECT: Always use .select() before .get() or .execute()
users = client.table("users").select("*").get()

# With filters - CORRECT: Use convenience methods (.gte()) or filter() method
adults = client.table("users") \
    .select("*") \
    .gte("age", 18) \
    .get()

# Or using filter() method
adults = client.table("users") \
    .select("*") \
    .filter("age", "gte", 18) \
    .get()

# Select specific columns - CORRECT
names = client.table("users") \
    .select("id", "name") \
    .get()

Advanced Queries

# Multiple filters with sorting
active_users = client.table("users") \
    .filter({"column": "status", "operator": "eq", "value": "active"}) \
    .filter({"column": "age", "operator": "gt", "value": 18}) \
    .order("created_at", "desc") \
    .limit(20) \
    .offset(0) \
    .get()

print(f"Found {active_users['count']} users")
for user in active_users["data"]:
    print(user["name"])

Filter Helper Methods

# Using helper methods (more readable)
users = client.table("users") \
    .eq("status", "active") \
    .gt("age", 18) \
    .like("email", "%@gmail.com") \
    .is_not_null("email_verified_at") \
    .in_("role", ["admin", "moderator"]) \
    .between("created_at", "2024-01-01", "2024-12-31") \
    .get()

# OR conditions
users = client.table("users") \
    .eq("status", "active") \
    .or_("role", "eq", "admin") \
    .get()

GROUP BY and Aggregates

Basic GROUP BY

# Group by category with counts
result = client.table("products") \
    .select("category", "COUNT(*) as count", "AVG(price) as avg_price") \
    .group_by("category") \
    .get()

# Group by date
result = client.table("orders") \
    .select("DATE(created_at) as date", "COUNT(*) as orders", "SUM(total) as revenue") \
    .group_by("DATE(created_at)") \
    .order_by("date", "desc") \
    .get()

# Multiple GROUP BY columns
result = client.table("sales") \
    .select("region", "category", "SUM(amount) as total") \
    .group_by("region", "category") \
    .get()

HAVING Clause

# Filter aggregated results
result = client.table("products") \
    .select("category", "COUNT(*) as count") \
    .group_by("category") \
    .having("COUNT(*)", "gt", 10) \
    .get()

# Multiple HAVING conditions
result = client.table("orders") \
    .select("DATE(created_at) as date", "SUM(total) as revenue") \
    .group_by("DATE(created_at)") \
    .having("SUM(total)", "gt", 1000) \
    .having("COUNT(*)", "gte", 5) \
    .get()

Multiple ORDER BY

# Order by multiple columns
result = client.table("products") \
    .select("*") \
    .order_by([("category", "asc"), ("price", "desc"), ("created_at", "desc")]) \
    .get()

CRUD Operations

Create Record

result = client.table("users").create({
    "name": "John Doe",
    "email": "john@example.com",
    "age": 30
})

print(f"Created user with ID: {result['id']}")

Update Record

client.table("users").update(123, {
    "email": "newemail@example.com"
})

print("User updated successfully")

Delete Record

client.table("users").delete(123)
print("User deleted successfully")

Get Single Record by ID

user = client.table("users").get_by_id(123)
print(f"User: {user['name']}")

Get First Record

# Get first matching record
user = client.table("users") \
    .filter({"column": "status", "operator": "eq", "value": "active"}) \
    .first()

if user:
    print(f"First active user: {user['name']}")

Filter Operators

Available operators for filtering data:

OperatorDescriptionExample
eqEquals{"column": "status", "operator": "eq", "value": "active"}
neqNot equals{"column": "status", "operator": "neq", "value": "deleted"}
gtGreater than{"column": "age", "operator": "gt", "value": 18}
gteGreater than or equal{"column": "age", "operator": "gte", "value": 18}
ltLess than{"column": "price", "operator": "lt", "value": 100}
lteLess than or equal{"column": "price", "operator": "lte", "value": 100}
likePattern matching{"column": "name", "operator": "like", "value": "john"}
isIS NULL / IS NOT NULL{"column": "deleted_at", "operator": "is", "value": "null"}
inIN operator{"column": "category", "operator": "in", "value": ["electronics", "books"]}
not_inNOT IN{"column": "status", "operator": "not_in", "value": ["deleted", "archived"]}
betweenBETWEEN{"column": "price", "operator": "between", "value": [10, 100]}
not_betweenNOT BETWEEN{"column": "age", "operator": "not_between", "value": [18, 65]}

Authentication

Use the same API key for authentication operations. The unified key system means one key works for both database and auth.

Sign Up & Sign In

from wowsql import WowSQLAuth

# Use the same API key as your database client
auth = WowSQLAuth(
    project_url="myproject",
    api_key="your_api_key"  # Same key as database client
)

# Sign up
result = auth.sign_up(
    email="user@example.com",
    password="SecurePassword123",
    full_name="John Doe"
)
print(f"Access token: {result['access_token']}")

# Sign in
login = auth.sign_in(
    email="user@example.com",
    password="SecurePassword123"
)
print(f"User ID: {login['user']['id']}")

Password Reset

# Request password reset
auth.forgot_password(email="user@example.com")

# Reset password with token from email
auth.reset_password(
    token="reset_token_from_email",
    new_password="NewSecurePassword123"
)

OTP Authentication

# Send OTP for login
auth.send_otp(email="user@example.com", purpose="login")

# Verify OTP and login
result = auth.verify_otp(
    email="user@example.com",
    otp="123456",
    purpose="login"
)
print(f"Logged in: {result['user']['id']}")

# Send OTP for signup
auth.send_otp(email="newuser@example.com", purpose="signup")

# Verify OTP and create account
result = auth.verify_otp(
    email="newuser@example.com",
    otp="123456",
    purpose="signup"
)

Magic Link & Email Verification

# Send magic link
auth.send_magic_link(email="user@example.com", purpose="login")

# Verify email with token
auth.verify_email(token="verification_token_from_email")

# Resend verification email
auth.resend_verification(email="user@example.com")

OAuth Authentication

# Get OAuth authorization URL
result = auth.get_oauth_authorization_url(
    provider="github",
    redirect_uri="http://localhost:5000/auth/callback"
)
# Redirect user to result["authorization_url"]

# After OAuth callback, exchange code for tokens
result = auth.exchange_oauth_callback(
    provider="github",
    code="authorization_code_from_callback"
)
print(f"OAuth login successful: {result['user']['id']}")

Error Handling

Wrap SDK calls in try/except to handle API and validation errors.

from wowsql import WowSQLClient, WowSQLError

try:
    users = client.table("users").select("*").get()
    print(f"Success: {len(users['data'])} users")
except WowSQLError as e:
    if e.status_code == 401:
        print("Authentication failed — check your API key")
    elif e.status_code == 404:
        print("Table or resource not found")
    else:
        print(f"Error ({e.status_code}): {e.message}")

Storage Operations

Initialize Storage

from wowsql import WowSQLStorage

# Use the same API key as your database client
storage = WowSQLStorage(
    project_url="myproject",
    api_key="your_api_key"  # Same key for all operations
)

File Operations

# Upload file
result = storage.upload_from_path(
    "path/to/document.pdf",
    "uploads/document.pdf",
    folder="documents"
)
print(f"Uploaded: {result['file_key']}")

# Get file URL (with metadata)
url_data = storage.get_file_url("uploads/document.pdf", expires_in=3600)
print(f"Download URL: {url_data['file_url']}")
print(f"Expires at: {url_data['expires_at']}")

# Get presigned URL (simple)
presigned_url = storage.get_presigned_url(
    "uploads/document.pdf",
    expires_in=3600,
    operation="get_object"
)
print(f"URL: {presigned_url}")

# List files
files = storage.list_files(prefix="uploads/")
for file in files:
    print(f"{file.key}: {file.size_mb:.2f} MB")

# Delete file
storage.delete_file("uploads/document.pdf")

# Check quota
quota = storage.get_quota()
print(f"Used: {quota.used_gb:.2f} GB / {quota.quota_gb:.2f} GB")

Download or View File

Via REST: use GET .../files/{file_key}/download for attachment download, or GET .../files/{file_key}/view to view inline in the browser.