NOTE

Literature Note: Supabase Flask Quickstart

acting_agentclaude-chronicler chunk_ids aliaseslit-supabase-flask, supabase-flask-quickstart sourcehttps://supabase.com/docs/guides/getting-started/quickstarts/flask retrieved_at2026-05-01 date2026-05-01 provenance titleLiterature Note: Supabase Flask Quickstart typeliterature source_record_ids authorclaude-sonnet-4-6 statusactive

Literature Note: Supabase Flask Quickstart

Official Supabase guide for connecting a Python Flask app to a Supabase project. Covers project creation, RLS configuration, Python client setup, and a minimal server-side rendering pattern.

Source Summary

Project Creation

Supabase projects are created via database.new (UI) or the Management API (programmatic, via curl with org ID, project name, region, database password).

Database Setup

create table instruments (
  id bigint primary key generated always as identity,
  name text not null
);

insert into instruments (name) values ('violin'), ('viola'), ('cello');

grant select on public.instruments to anon;
alter table instruments enable row level security;
create policy "public can read instruments" on public.instruments
  for select to anon using (true);

RLS is enabled from the start; the anon role is granted read via an explicit policy.

Python Environment

mkdir my-app && cd my-app
python3 -m venv venv
source venv/bin/activate
pip install flask supabase python-dotenv

Configuration

.env file holds two values retrieved from the project's Connect dialog:

SUPABASE_URL=
SUPABASE_PUBLISHABLE_KEY=

Application Code

import os
from flask import Flask
from supabase import create_client, Client
from dotenv import load_dotenv

load_dotenv()
app = Flask(__name__)

supabase: Client = create_client(
    os.environ.get("SUPABASE_URL"),
    os.environ.get("SUPABASE_PUBLISHABLE_KEY")
)

@app.route('/')
def index():
    response = supabase.table('instruments').select("*").execute()
    instruments = response.data
    html = '<h1>Instruments</h1><ul>'
    for instrument in instruments:
        html += f'<li>{instrument["name"]}</li>'
    html += '</ul>'
    return html

if __name__ == '__main__':
    app.run(debug=True)

Key Observations

  • create_client() is called once at module level — acts as a connection singleton
  • Query API is method-chained: .table().select().execute()
  • Response data lives in .data attribute of the returned object
  • Authorization is handled entirely by RLS, not application logic
  • SUPABASE_PUBLISHABLE_KEY (not the secret service key) is used — safe for server environments without full privilege escalation risk

Links