Supabase API API in Python
Supabase API API in Python
This guide shows you how to integrate the Supabase API into your Python application. Open-source Firebase alternative with PostgreSQL, Auth, Storage, and Realtime.
Prerequisites
- Python installed on your system
- An Supabase API API key (sign up at https://supabase.com)
- Basic familiarity with HTTP APIs
Installation
pip install requests python-dotenv
Basic Usage
import os
import requests
API_KEY = os.environ.get("API_KEY", "YOUR_API_KEY")
BASE_URL = "https://api.supabase.com"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
response = requests.get(f"{BASE_URL}/v1/resources", headers=headers)
print(f"Status: {response.status_code}")
print(response.json())
Error Handling
import requests
import time
def call_api_with_retry(url, headers, max_retries=3):
for attempt in range(max_retries):
try:
response = requests.get(url, headers=headers, timeout=30)
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 60))
print(f"Rate limited. Waiting {retry_after}s...")
time.sleep(retry_after)
continue
response.raise_for_status()
return response.json()
except requests.exceptions.Timeout:
print(f"Timeout on attempt {attempt + 1}")
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
if attempt == max_retries - 1:
raise
time.sleep(2 ** attempt)
result = call_api_with_retry(
f"{BASE_URL}/v1/resources",
headers={"Authorization": f"Bearer {API_KEY}"}
)
Advanced Usage
import os
import requests
from typing import Optional, Dict, List
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class SupabaseClient:
"""Advanced client for Supabase API."""
def __init__(self, api_key: str, base_url: str = "https://api.supabase.com"):
self.api_key = api_key
self.base_url = base_url.rstrip("/")
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
"User-Agent": "Supabase API/1.0"
})
def list_resources(self, params: Dict = None) -> List[Dict]:
"""List resources with pagination."""
all_results = []
cursor = None
while True:
if cursor:
params = params or {}
params["cursor"] = cursor
response = self.session.get(
f"{self.base_url}/v1/resources",
params=params,
timeout=30
)
response.raise_for_status()
data = response.json()
all_results.extend(data.get("data", []))
cursor = data.get("next_cursor")
if not cursor:
break
return all_results
def create_resource(self, data: Dict) -> Dict:
"""Create a new resource."""
response = self.session.post(
f"{self.base_url}/v1/resources",
json=data,
timeout=30
)
response.raise_for_status()
return response.json()
client = SupabaseClient(os.environ["API_KEY"])
resources = client.list_resources(params={"limit": 50})
print(f"Found {len(resources)} resources")
Best Practices
- Store your API key in an environment variable, never in source code
- Implement retry logic with exponential backoff for 429 and 5xx errors
- Set reasonable timeouts (10-30 seconds) for all API calls
- Log request IDs from response headers for debugging
- Cache responses where appropriate to reduce API calls