mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Docs update — adds a new framework quickstart. ## What is the current behavior? The Framework Quickstarts section under Getting Started covers Next.js, Nuxt, React, Flask, and others, but doesn't include Reflex (https://reflex.dev), an open-source Python web framework that compiles to React. Python developers building full-stack apps with Reflex have to piece together the Supabase setup from the general Python reference rather than following a quickstart. ## What is the new behavior? Adds a Reflex framework quickstart at `apps/docs/content/guides/getting-started/quickstarts/reflex.mdx`, mirroring the structure of the existing Flask quickstart: same DB setup partial (`quickstart_db_setup.mdx`), same env var step using `ProjectConfigVariables`, same six-step `StepHikeCompact` shape. A nav entry is added directly after Flask in `NavigationMenu.constants.ts`, gated on `!jsOnly` to match Flask's pattern. Verified end-to-end against a fresh Supabase project: ran every command in the docs literally, including the full SQL from `quickstart_db_setup.mdx` (with the `grant select on public.instruments to anon` line). The rendered Reflex app shows the Instruments heading with all three seeded rows. No console errors, no event-loop warnings. ## Additional context Conventions used in the quickstart: - Uses `uv` (`uv init`, `uv add`, `uv run`) rather than pip + venv. This follows the broader docs pattern of each quickstart using its framework's idiomatic tooling (Next.js → npx, RedwoodJS → yarn, Laravel → composer, Flutter → pubspec.yaml). It also matches what Reflex's own `reflex init` post-install message recommends. `uv add` produces a `pyproject.toml` and `uv.lock` so users can rebuild deterministically with `uv sync`. - The Supabase client is constructed via `acreate_client` with a lazy-init pattern, and the event handler is `async def`. This avoids blocking Reflex's event loop on the HTTP request. In touch with the Supabase team on this — happy to iterate on copy or scope based on review. Pre-flight: ran pnpm run format locally, which passed cleanly. Did not run pnpm run build locally — hit a Windows/CRLF-related TOML parsing failure in an unrelated troubleshooting frontmatter file (apps/docs/content/troubleshooting/all-about-supabase-egress-a_Sg_e.mdx) during page data collection. Relying on Vercel preview to validate the build. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Reflex (Python) and Spring Boot to the framework quickstarts. * Reorganized quickstart listings for clearer framework navigation and grouping. * **Documentation** * Added a Reflex quickstart guide covering Supabase setup, environment variables, asynchronous data loading, error handling, and running the app. * Added Reflex-specific AI guidance for configuring Supabase projects. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Nik Richers <nik@validmind.ai>
131 lines
3.8 KiB
Plaintext
131 lines
3.8 KiB
Plaintext
---
|
|
title: 'Use Supabase with Reflex'
|
|
subtitle: 'Learn how to create a Supabase project, add some sample data to your database, and query the data from a Reflex app.'
|
|
breadcrumb: 'Framework Quickstarts'
|
|
---
|
|
|
|
<AiPrompt id="reflex" />
|
|
|
|
<$Partial path="quickstart_db_setup.mdx" />
|
|
|
|
## 3. Create a Reflex app
|
|
|
|
Create a new directory for your Reflex app, initialize a project with `uv`, add Reflex as a dependency, and scaffold a blank app with `--template blank`.
|
|
|
|
```bash
|
|
mkdir my_app && cd my_app
|
|
uv init
|
|
uv add reflex
|
|
uv run reflex init --template blank
|
|
```
|
|
|
|
## 4. Set up AI tooling (optional)
|
|
|
|
<$Partial path="quickstart_ai_tooling.mdx" />
|
|
|
|
## 5. Install the Supabase client library
|
|
|
|
The fastest way to get started is to use the `supabase-py` client library, which provides a convenient interface for working with Supabase from a Reflex app.
|
|
|
|
Install `supabase-py` and `python-dotenv` to load environment variables.
|
|
|
|
```bash
|
|
uv add supabase python-dotenv
|
|
```
|
|
|
|
## 6. Declare Supabase environment variables
|
|
|
|
Create a `.env` file in your project root and populate it with your Supabase connection variables that you can get from the helper below, or [from the project **Connect** panel](/dashboard/project/_?showConnect=true&connectTab=frameworks):
|
|
|
|
<Button variant="primary" asChild>
|
|
<a href="/dashboard/project/_?showConnect=true&connectTab=frameworks">Open Connect panel</a>
|
|
</Button>
|
|
|
|
```text name=.env
|
|
SUPABASE_URL=<SUBSTITUTE_SUPABASE_URL>
|
|
SUPABASE_PUBLISHABLE_KEY=<SUBSTITUTE_SUPABASE_PUBLISHABLE_KEY>
|
|
```
|
|
|
|
<$Partial path="api_settings.mdx" variables={{ "framework": "", "tab": "" }} />
|
|
|
|
## 7. Create the Supabase client
|
|
|
|
Open `my_app/my_app.py` and add the following code to create an async Supabase client from your environment variables. Reflex's event handlers run inside an async event loop, so the client is created once with `acreate_client` and reused across requests, rather than recreated per page load.
|
|
|
|
```python name=my_app/my_app.py
|
|
import os
|
|
import reflex as rx
|
|
from supabase import acreate_client, AsyncClient
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
_supabase: AsyncClient | None = None
|
|
|
|
|
|
async def get_supabase() -> AsyncClient:
|
|
global _supabase
|
|
if _supabase is None:
|
|
_supabase = await acreate_client(
|
|
os.environ.get("SUPABASE_URL"),
|
|
os.environ.get("SUPABASE_PUBLISHABLE_KEY"),
|
|
)
|
|
return _supabase
|
|
```
|
|
|
|
## 8. Query data from the app
|
|
|
|
Add a `State` class that holds the query result, an async event handler that fetches data from your `instruments` table, and a page that renders the result. `on_load` triggers the handler when the page is opened.
|
|
|
|
```python name=my_app/my_app.py
|
|
from postgrest import APIError
|
|
|
|
|
|
class State(rx.State):
|
|
instruments: list[dict] = []
|
|
error: str = ""
|
|
|
|
async def load_instruments(self):
|
|
supabase = await get_supabase()
|
|
try:
|
|
response = await supabase.table("instruments").select("*").execute()
|
|
except APIError as error:
|
|
self.error = f"Error loading instruments: {error.message}"
|
|
return
|
|
self.instruments = response.data
|
|
|
|
|
|
def index() -> rx.Component:
|
|
return rx.container(
|
|
rx.heading("Instruments"),
|
|
rx.cond(
|
|
State.error,
|
|
rx.text(State.error),
|
|
rx.foreach(
|
|
State.instruments,
|
|
lambda instrument: rx.text(instrument["name"]),
|
|
),
|
|
),
|
|
)
|
|
|
|
|
|
app = rx.App()
|
|
app.add_page(index, on_load=State.load_instruments)
|
|
```
|
|
|
|
## 9. Start the app
|
|
|
|
Run the Reflex development server, go to http://localhost:3000 in a browser, and you should see the list of instruments.
|
|
|
|
```bash
|
|
uv run reflex run
|
|
```
|
|
|
|
<$Partial path="quickstart_going_to_production.mdx" />
|
|
|
|
## Next steps
|
|
|
|
- Set up [Auth](/docs/guides/auth) for your app
|
|
- [Insert more data](/docs/guides/database/import-data) into your database
|
|
- Upload and serve static files using [Storage](/docs/guides/storage)
|