Supabase gives you a complete backend — database, authentication, storage, and real-time subscriptions — with auto-generated REST and GraphQL APIs. The free tier includes 500MB database, 1GB storage, and 50K monthly active users.
Why Use Supabase?
- Instant API from your PostgreSQL database
- Auth with email, OAuth, magic links — built in
- Real-time subscriptions via WebSockets
- Storage for files with CDN delivery
- Free tier generous enough for production MVPs
Getting Started
Get your project URL and API key from supabase.com > Project Settings > API:
export SUPABASE_URL="https://your-project.supabase.co"
export SUPABASE_KEY="your-anon-key"
# Query data
curl -s "$SUPABASE_URL/rest/v1/products?select=*&limit=5" \
-H "apikey: $SUPABASE_KEY" \
-H "Authorization: Bearer $SUPABASE_KEY" | jq .
# Insert data
curl -s "$SUPABASE_URL/rest/v1/products" \
-H "apikey: $SUPABASE_KEY" \
-H "Authorization: Bearer $SUPABASE_KEY" \
-H "Content-Type: application/json" \
-H "Prefer: return=representation" \
-d '{"name": "Widget Pro", "price": 29.99, "category": "tools"}' | jq .
Python Client
from supabase import create_client
supabase = create_client('https://your-project.supabase.co', 'your-anon-key')
# Query with filters
result = supabase.table('products').select('*').eq('category', 'electronics').lt('price', 100).order('price').limit(10).execute()
for product in result.data:
print(f"{product['name']:30s} ${product['price']:.2f}")
# Insert
new = supabase.table('products').insert({'name': 'Gadget X', 'price': 49.99, 'category': 'electronics'}).execute()
print(f"Created: {new.data[0]['id']}")
# Update
supabase.table('products').update({'price': 39.99}).eq('id', 1).execute()
# Delete
supabase.table('products').delete().eq('id', 1).execute()
Authentication
# Sign up
result = supabase.auth.sign_up({'email': 'user@example.com', 'password': 'secure-password'})
print(f"User ID: {result.user.id}")
# Sign in
result = supabase.auth.sign_in_with_password({'email': 'user@example.com', 'password': 'secure-password'})
token = result.session.access_token
print(f"Token: {token[:20]}...")
# OAuth
result = supabase.auth.sign_in_with_oauth({'provider': 'github'})
print(f"Redirect URL: {result.url}")
File Storage
# Upload a file
with open('report.pdf', 'rb') as f:
supabase.storage.from_('documents').upload('reports/q1-2026.pdf', f)
# Get public URL
url = supabase.storage.from_('documents').get_public_url('reports/q1-2026.pdf')
print(f"Public URL: {url}")
# List files
files = supabase.storage.from_('documents').list('reports/')
for file in files:
print(f"{file['name']:30s} {file['metadata']['size']:>10d} bytes")
# Generate signed URL (temporary access)
signed = supabase.storage.from_('documents').create_signed_url('reports/q1-2026.pdf', 3600)
print(f"Signed URL (1 hour): {signed['signedURL']}")
Real-Time Subscriptions
def handle_change(payload):
event = payload['eventType']
record = payload.get('new', payload.get('old', {}))
print(f"[{event}] {record}")
# Subscribe to table changes
supabase.table('orders').on('*', handle_change).subscribe()
# Subscribe to specific events
supabase.table('orders').on('INSERT', lambda p: print(f"New order: {p['new']}")).subscribe()
supabase.table('orders').on('UPDATE', lambda p: print(f"Order updated: {p['new']}")).subscribe()
Edge Functions
# Deploy an Edge Function
supabase functions deploy hello-world
# Call it
curl -s "$SUPABASE_URL/functions/v1/hello-world" \
-H "Authorization: Bearer $SUPABASE_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "World"}'
// supabase/functions/hello-world/index.ts
Deno.serve(async (req) => {
const { name } = await req.json();
return new Response(JSON.stringify({ message: `Hello, ${name}!` }), {
headers: { 'Content-Type': 'application/json' }
});
});
Row-Level Security
-- Users can only see their own data
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users see own orders" ON orders
FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "Users create own orders" ON orders
FOR INSERT WITH CHECK (auth.uid() = user_id);
Full-Stack App in 50 Lines
from supabase import create_client
from flask import Flask, request, jsonify
app = Flask(__name__)
db = create_client('https://your-project.supabase.co', 'your-service-key')
@app.route('/api/products', methods=['GET'])
def list_products():
category = request.args.get('category')
query = db.table('products').select('*')
if category:
query = query.eq('category', category)
result = query.order('created_at', desc=True).limit(50).execute()
return jsonify(result.data)
@app.route('/api/products', methods=['POST'])
def create_product():
result = db.table('products').insert(request.json).execute()
return jsonify(result.data[0]), 201
@app.route('/api/products/<int:id>', methods=['PUT'])
def update_product(id):
result = db.table('products').update(request.json).eq('id', id).execute()
return jsonify(result.data[0])
@app.route('/api/products/<int:id>', methods=['DELETE'])
def delete_product(id):
db.table('products').delete().eq('id', id).execute()
return '', 204
if __name__ == '__main__':
app.run(port=5000)
Real-World Use Case
A two-person startup built a complete SaaS product using Supabase as their entire backend. Database, auth, file storage, real-time chat — all powered by Supabase APIs. They went from idea to paying customers in 3 weeks, with $0 infrastructure costs on the free tier. When they scaled to 10K users, they upgraded to the $25/month plan.
What You Can Build
- Full-stack app without writing backend code
- Real-time dashboard with live data updates
- SaaS platform with auth and multi-tenancy
- File management system with CDN delivery
- Mobile app backend with offline sync
Need custom backend solutions? I build APIs and full-stack applications.
Email me: spinov001@gmail.com
Check out my developer tools: https://apify.com/spinov001
Top comments (0)