Supabase SDK — Using the Client Library for Database and Auth Operations
In this tutorial, you will learn about Supabase SDK. We cover key concepts, practical examples, and best practices to help you master this topic.
The Supabase SDK provides a client library that wraps all Supabase services (database, auth, storage, realtime, and functions) into a single consistent API for JavaScript, Python, and other languages.
What You'll Learn
By the end of this lesson you will perform CRUD operations with filters and pagination, manage auth state, use the realtime subscription API, handle errors, and implement the SDK in both frontend and backend contexts.
Why It Matters
The SDK is the primary way most applications interact with Supabase. Mastering its API patterns -- query building, session management, subscriptions -- is essential for productive development.
Real-World Use
DodaZIP uses the Supabase Python SDK for backend services and the JavaScript SDK for the frontend. Both share the same API patterns, making it easy to move code between server and client.
flowchart LR
A[Python Backend] -->|SDK| API[Supabase]
B[JavaScript Frontend] -->|SDK| API
C[Mobile App] -->|SDK| API
API --> DB[(PostgreSQL)]
API --> Auth[Auth Service]
API --> Storage[Storage]
style API fill:#3ecf8e,color:#fff
Querying Data
Perform database queries with the SDK.
# query_data.py
# Database queries with the Supabase SDK
import os
from supabase import create_client
url = os.getenv("SUPABASE_URL", "https://example.supabase.co")
key = os.getenv("SUPABASE_ANON_KEY", "your-anon-key")
supabase = create_client(url, key)
def basic_queries():
# Get all rows
result = supabase.table("files").select("*").execute()
print(f"All files: {len(result.data)} rows")
# Get with filter
result = supabase.table("files") \
.select("*") \
.eq("user_id", "user_abc") \
.execute()
print(f"User files: {len(result.data)} rows")
# Get single row
result = supabase.table("files") \
.select("*") \
.eq("id", "file_123") \
.single() \
.execute()
print(f"Single file: {result.data}")
# Order and limit
result = supabase.table("files") \
.select("*") \
.order("created_at", desc=True) \
.limit(10) \
.execute()
print(f"Latest 10 files: {len(result.data)} rows")
basic_queries()
Insert, Update, and Delete
CRUD operations with the SDK.
# crud_operations.py
# Create, update, and delete operations
def crud_examples():
supabase = create_client(
os.getenv("SUPABASE_URL", "https://example.supabase.co"),
os.getenv("SUPABASE_ANON_KEY", "your-anon-key")
)
# Insert a new file record
data = {
"user_id": "user_abc",
"name": "report.pdf",
"size_bytes": 1024000,
"mime_type": "application/pdf",
}
result = supabase.table("files").insert(data).execute()
print(f"Inserted file: {result.data}")
# Update a record
result = supabase.table("files") \
.update({"status": "processed"}) \
.eq("id", "file_123") \
.execute()
print(f"Updated file: {result.data}")
# Delete a record
result = supabase.table("files") \
.delete() \
.eq("id", "file_456") \
.execute()
print(f"Deleted file count: {len(result.data)}")
# Upsert (insert or update)
result = supabase.table("files").upsert({
"id": "file_789",
"name": "updated-report.pdf",
"size_bytes": 2048000,
}).execute()
print(f"Upserted file: {result.data}")
crud_examples()
Authentication with SDK
Manage user auth through the SDK.
# auth_sdk.py
# Authentication operations with the SDK
def auth_examples():
supabase = create_client(
os.getenv("SUPABASE_URL", "https://example.supabase.co"),
os.getenv("SUPABASE_ANON_KEY", "your-anon-key")
)
# Get current session
session = supabase.auth.get_session()
if session:
print(f"Logged in as: {session.user.email}")
else:
print("Not logged in")
# Listen for auth state changes
def on_auth_state_change(event, session):
print(f"Auth event: {event}")
if session:
print(f"User: {session.user.email}")
subscription = supabase.auth.on_auth_state_change(on_auth_state_change)
print("Listening for auth state changes...")
# Update user metadata
result = supabase.auth.update_user({
"data": {"full_name": "Alice Johnson"}
})
print(f"Updated user metadata: {result}")
auth_examples()
Error Handling
Properly handle SDK errors.
# error_handling.py
# Handling SDK errors
from supabase import create_client
from supabase.lib.client_options import ClientOptions
def handle_sdk_errors():
supabase = create_client(
"https://example.supabase.co",
"invalid-key"
)
try:
result = supabase.table("files").select("*").execute()
print(f"Query succeeded: {result}")
except Exception as e:
error_msg = str(e)
if "401" in error_msg:
print(f"Auth error: Invalid API key or session")
elif "404" in error_msg:
print(f"Not found: Table or row does not exist")
elif "400" in error_msg:
print(f"Bad request: {e}")
elif "row-level security" in error_msg.lower():
print(f"Policy error: RLS policy blocked the operation")
else:
print(f"Unexpected error: {e}")
handle_sdk_errors()
Common Mistakes
Not awaiting queries: The SDK returns promises in JavaScript and coroutines in Python. Forgetting to await results in accessing pending promises.
Using service_role key on the client: The service_role key bypasses RLS. Use the anon key for client-side code and the service_role key only in secure backend contexts.
Not handling authentication errors: Failed auth operations throw exceptions. Always wrap auth calls in try/catch blocks.
Chaining methods incorrectly: The SDK uses method chaining. Operations like
.eq().order().limit()must be chained in the correct order after.select().Forgetting to enable RLS on new tables: If you insert data via the SDK without RLS enabled, users may see data they should not have access to.
Practice Questions
How do you query rows where a column equals a specific value? Use
.eq("column", "value")chained after.select("*").How do you insert multiple rows at once? Pass a list of dictionaries to
.insert().How do you update rows matching a condition? Chain
.update({"column": "value"}).eq("id", "target_id").What is the difference between insert and upsert? Upsert inserts a new row or updates an existing one if it conflicts on a unique constraint.
Challenge: Build a complete CRUD API wrapper using the Supabase SDK that handles authentication, validation, error handling, and pagination for a file management system.
FAQ
Mini Project
Create a data access layer using the Supabase SDK that provides typed CRUD operations, authentication, and error handling for the file management system.
class FileRepository:
def __init__(self, supabase_client):
self.supabase = supabase_client
self.table = supabase_client.table("files")
def get_user_files(self, user_id, page=1, per_page=20):
start = (page - 1) * per_page
end = start + per_page - 1
result = self.table.select("*") \
.eq("user_id", user_id) \
.order("created_at", desc=True) \
.range(start, end) \
.execute()
return result.data
def create_file(self, file_data):
result = self.table.insert(file_data).execute()
return result.data[0]
def delete_file(self, file_id, user_id):
result = self.table.delete() \
.eq("id", file_id) \
.eq("user_id", user_id) \
.execute()
return len(result.data) > 0
# Usage
repo = FileRepository(supabase)
files = repo.get_user_files("user_abc")
print(f"Retrieved {len(files)} files")
What's Next
Next: Supabase REST API for direct API access without the SDK.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro