Supabase Database

PostgreSQL with REST API and real-time subscriptions for AI agents

Supabase provides PostgreSQL with a built-in REST API, authentication, and real-time features, perfect for rapid AI agent development.

python
import os
from praisonaiagents import Agent, MemoryConfig

agent = Agent(
    name="assistant",
    instructions="You are helpful with persistent memory.",
    memory=MemoryConfig(
        db={
            "database_url": os.environ["SUPABASE_URL"],
            "supabase_key": os.environ["SUPABASE_KEY"],
        },
    ))
agent.start("Remember that I am building a chatbot")

The user stores facts; Supabase-backed db config persists memory across sessions.

Diagram

Supabase Dual Mode

REST API

Direct SQL

πŸ€– Agent

πŸ”€ Connection Mode

🌐 Supabase REST

🐘 PostgreSQL

πŸ“‘ REST API

πŸ’Ύ SQL Database

πŸ—„οΈ Storage

⏸️ Auto-Pause

How It Works

Diagram
Supabase DatabaseAgentUserSupabase DatabaseAgentUserRequestProcess requestResult Agent–>>User: Response

Quick Start

  1. Choose Connection Mode

    Supabase offers two connection methods:

    REST API (Recommended)

    python
    import os
    from praisonaiagents import Agent, MemoryConfig
    
    agent = Agent(
        name="Supabase Agent",
        instructions="You are a helpful assistant with persistent memory.",
        memory=MemoryConfig(
            db={
                "database_url": os.environ["SUPABASE_URL"],
                "supabase_key": os.environ["SUPABASE_KEY"],
            },
        ))

    Direct PostgreSQL

    python
    from praisonaiagents import Agent, MemoryConfig
    
    agent = Agent(
        name="Supabase Direct Agent", 
        instructions="You are a helpful assistant with SQL persistence.",
        memory=MemoryConfig(
            db={"database_url": "postgresql://postgres:pass@db.xxx.supabase.com:5432/postgres"},
        ))
  2. Set Environment Variables
    bash
    # For REST API mode
    export SUPABASE_URL="https://your-project.supabase.co"
    export SUPABASE_KEY="your-anon-or-service-role-key"
    
    # Or for direct PostgreSQL mode  
    export SUPABASE_DATABASE_URL="postgresql://postgres:pass@db.xxx.supabase.com:5432/postgres"
  3. Test Conversation
    python
    # Start conversation
    result = agent.start("I'm working on a chatbot project using Supabase")
    print(result)
    
    # Later session - memory persists
    result = agent.start("What project was I working on?") 
    print(result)  # "You were working on a chatbot project using Supabase"

Installation

REST API Mode

bash
# Install Supabase client
pip install supabase

Direct PostgreSQL Mode

bash
# Install PostgreSQL driver
pip install "praisonai[neon]"

Connection Modes

REST API Mode

Uses Supabase’s REST API with automatic schema generation:

python
from praisonaiagents import Agent, MemoryConfig

agent = Agent(
    name="REST Agent",
    instructions="You use Supabase REST API for persistence.",
    memory=MemoryConfig(
        db={
            "database_url": "https://xxx.supabase.co",
            "supabase_key": os.environ["SUPABASE_KEY"],
        },
    ))

# Tables are created automatically via REST API
result = agent.start("Hello from Supabase REST!")

Required Tables (auto-created):

sql
-- Create in Supabase SQL Editor if not using auto-creation
CREATE TABLE praison_sessions (
    session_id TEXT PRIMARY KEY,
    user_id TEXT,
    agent_id TEXT,
    name TEXT,
    state JSONB,
    metadata JSONB,
    created_at DOUBLE PRECISION,
    updated_at DOUBLE PRECISION
);

CREATE TABLE praison_messages (
    id TEXT PRIMARY KEY,
    session_id TEXT REFERENCES praison_sessions(session_id),
    role TEXT NOT NULL,
    content TEXT,
    tool_calls JSONB,
    metadata JSONB,
    created_at DOUBLE PRECISION
);

Direct PostgreSQL Mode

Uses standard PostgreSQL connection through Supabase’s pooler:

python
from praisonaiagents import Agent, MemoryConfig

agent = Agent(
    name="Direct Agent",
    instructions="You use direct PostgreSQL for persistence.",
    memory=MemoryConfig(
        db={"database_url": "postgresql://postgres:pass@db.xxx.supabase.com:6543/postgres"},
    ))

# Standard PostgreSQL tables with auto-retry for paused projects
result = agent.start("Hello from Supabase PostgreSQL!")

Configuration Options

OptionREST ModeDirect ModeDescription
database_urlhttps://xxx.supabase.copostgresql://...Supabase URL
supabase_keyβœ… Required❌API key (anon or service_role)
max_retries33Retries for paused project recovery
retry_delay2.00.5Base delay between retries
auto_create_tablesTrueTrueCreate tables automatically

Usage Patterns

Environment-Based Setup

python
import os
from praisonaiagents import Agent, MemoryConfig

# REST API mode - auto-detects from environment
agent = Agent(
    name="Auto Agent",
    instructions="You auto-configure from environment.",
    memory=MemoryConfig(
        db=True,  # Uses SUPABASE_URL + SUPABASE_KEY
    ))

Manual REST Configuration

python
from praisonai.persistence.conversation.supabase import SupabaseConversationStore
from praisonaiagents import Agent, MemoryConfig

store = SupabaseConversationStore(
    url="https://your-project.supabase.co",
    key=os.environ["SUPABASE_KEY"],
    max_retries=5,  # Extra retries for paused projects
    retry_delay=3.0  # 3 second delays
)

agent = Agent(name="Manual Agent", memory={"db": store})

Full Lifecycle Example

python
import os
from praisonai import ManagedAgent, LocalManagedConfig  
from praisonaiagents import Agent, MemoryConfig

# Phase 1: Create agent with Supabase REST
managed = ManagedAgent(
    provider="local",
    db={
        "database_url": os.environ["SUPABASE_URL"],
        "supabase_key": os.environ["SUPABASE_KEY"]
    },
    config=LocalManagedConfig(
        model="gpt-4o-mini",
        name="Supabase Demo",
        system="You are a helpful assistant with Supabase persistence."
    )
)

agent = Agent(name="User", backend=managed)

# Store conversation data
result1 = agent.run("I'm building a real-time chat app with Supabase")
print(f"Agent: {result1}")

result2 = agent.run("The app needs user auth and database subscriptions")
print(f"Agent: {result2}")

# Phase 2: Save and simulate project pause (free tier)
session_data = managed.save_ids()
del agent, managed  # Simulate pause

# Phase 3: Resume after project wake-up
managed2 = ManagedAgent(
    provider="local",
    db={
        "database_url": os.environ["SUPABASE_URL"],
        "supabase_key": os.environ["SUPABASE_KEY"]
    }
)
managed2.resume_session(session_data["session_id"])

agent2 = Agent(name="User", backend=managed2) 
result3 = agent2.run("What kind of app am I building?")
print(f"Resumed Agent: {result3}")
# Should recall: real-time chat app with auth and subscriptions

Supabase-Specific Features

Paused Project Recovery

Free tier projects auto-pause after 1 week of inactivity. PraisonAI handles wake-up automatically:

python
from praisonai.persistence.conversation.supabase import SupabaseConversationStore

store = SupabaseConversationStore(
    url="https://paused-project.supabase.co",
    key=os.environ["SUPABASE_KEY"],
    max_retries=5,  # Extra retries for wake-up
    retry_delay=3.0  # Longer delays for project start
)

# First request may take 30-60 seconds if project was paused
# Subsequent requests are fast

Row Level Security (RLS)

Enable RLS in Supabase for multi-tenant agents:

sql
-- Enable RLS on tables
ALTER TABLE praison_sessions ENABLE ROW LEVEL SECURITY;
ALTER TABLE praison_messages ENABLE ROW LEVEL SECURITY;

-- Policy: Users can only access their own sessions
CREATE POLICY "Users can access own sessions" ON praison_sessions
    FOR ALL USING (user_id = auth.uid()::text);

-- Policy: Users can access messages from their sessions
CREATE POLICY "Users can access own messages" ON praison_messages  
    FOR ALL USING (
        session_id IN (
            SELECT session_id FROM praison_sessions WHERE user_id = auth.uid()::text
        )
    );
python
# Use service_role key for admin access, or implement user auth
agent = Agent(
    name="Multi-Tenant Agent",
    memory=MemoryConfig(
        db={
            "database_url": "https://xxx.supabase.co",
            "supabase_key": os.environ["SUPABASE_SERVICE_KEY"]  # service_role key bypasses RLS
        },
    ))

Real-time Subscriptions

Listen to conversation changes in real-time:

python
import asyncio
from supabase import create_client

async def listen_to_conversations():
    supabase = create_client(
        "https://your-project.supabase.co",
        os.environ["SUPABASE_KEY"],
    )

    def on_message(payload):
        print(f"New message: {payload}")

    # Subscribe to new messages
    supabase.table("praison_messages").on("INSERT", on_message).subscribe()

    # Keep listening
    await asyncio.sleep(3600)  # Listen for 1 hour

# Run in background
asyncio.create_task(listen_to_conversations())

Best Practices

Choose the Right Mode
  • REST API: Best for rapid prototyping, automatic pausing recovery, built-in auth
  • Direct PostgreSQL: Better performance, lower latency, standard SQL features
python
# REST: Easy setup, handles paused projects
rest_agent = Agent(memory={"db": {"database_url": "https://xxx.supabase.co", "supabase_key": "..."}})

# Direct: Better for production, lower latency  
direct_agent = Agent(memory={"db": {"database_url": "postgresql://postgres:pass@db.xxx.supabase.com:6543/postgres"}})
Handle Project Pausing

Free tier projects pause after 1 week. Design for graceful wake-up:

python
from praisonai.persistence.conversation.supabase import SupabaseConversationStore

# Optimize for paused project recovery
store = SupabaseConversationStore(
    url="https://project.supabase.co",
    key=os.environ["SUPABASE_KEY"],
    max_retries=10,  # More retries for wake-up
    retry_delay=5.0   # Longer delays
)
Use Service Role Keys Carefully

Service role keys bypass Row Level Security. Use them only for admin operations:

python
# Anon key (limited permissions)
public_agent = Agent(memory={"db": {"supabase_key": os.environ["SUPABASE_KEY"]}})

# Service role (full access) β€” use carefully
admin_agent = Agent(memory={"db": {"supabase_key": os.environ["SUPABASE_SERVICE_KEY"]}})
Monitor Usage

Track your Supabase usage:

  • Database size: Conversation history grows over time
  • API requests: REST calls count toward monthly limits
  • Bandwidth: File uploads/downloads if using storage

Set up usage alerts in the Supabase dashboard.


Environment Variables

VariableModeFormatExample
SUPABASE_URLRESThttps://xxx.supabase.cohttps://abcdefgh.supabase.co
SUPABASE_KEYRESTJWT tokenFrom Supabase dashboard β†’ Settings β†’ API
SUPABASE_DATABASE_URLDirectpostgresql://...postgresql://postgres:pass@db.xxx.supabase.com:5432/postgres
OPENAI_API_KEYBothAPI keySet in environment for LLM calls

Troubleshooting

Project Paused Error

If you get “project is paused” errors:

python
# Wait 30-60 seconds for project to wake up, or upgrade to Pro plan
store = SupabaseConversationStore(max_retries=10, retry_delay=10.0)

API Key Permissions

Ensure your API key has the right permissions:

bash
# Check key type in Supabase dashboard
# anon key: Limited to RLS policies
# service_role key: Full database access

SSL Connection Issues

For direct PostgreSQL mode, ensure SSL:

python
# Add SSL to connection string
db_url = "postgresql://postgres:pass@db.xxx.supabase.com:6543/postgres?sslmode=require"

Related