Self-hosted service
supabase/supabase-py avatar
supabase/supabase-py

supabase-py: a Python monorepo for Postgres, auth, storage, and realtime

Python Client for Supabase. Query Postgres from Flask, Django, FastAPI. Python user authentication, security policies, edge functions, file storage, and realtime data streaming. Good first issue.

2,578 stars553 forksPythonMIT

At a glance

What is it?
supabase-py packages six Supabase client libraries into one uv workspace, so a Python service can talk to Postgres, GoTrue auth, storage, edge functions, and realtime channels through separate installable modules. The design is sensible for teams already on Supabase, and the repository layout tells you more about its maintenance model than the README does.
Who is it for?
Adopt supabase-py if your backend already lives on a Supabase project and you want auth, storage, functions, and realtime behind one Python dependency set; skip it if you only need SQL access to a Postgres instance you host yourself, because psycopg or SQLAlchemy will do that without pulling in the Supabase auth and realtime layers.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem supabase-py solves is not SQL access, it is the surrounding services

Python already has mature ways to talk to Postgres. What it does not have is a single client that also speaks to the rest of a Supabase project: the auth service, the storage buckets, the edge functions, and the realtime websocket channel. supabase-py exists to fill that gap. The repository is described in its own README as a "Python monorepo for all Supabase libraries", and it lists six of them: supabase, realtime-py, supabase_functions, storage3, postgrest, and supabase_auth. Each has its own README under src/, and each is a separately installable piece rather than a single monolithic SDK. That split matters. A Django service that only needs row-level-secured queries can depend on postgrest alone and never load the realtime websocket code. A FastAPI app that only needs to verify a user's session can take supabase_auth on its own. The audience is Python backend developers who have already chosen Supabase as their backend platform, or who are evaluating it, and who do not want to hand-roll HTTP calls against four different Supabase endpoints with four different auth header conventions.

Six subpackages, one uv workspace, and why the split is the architecture

The architecture visible in the repository is a workspace layout, not a layered library. The README states that the repo relies on uv for Python project management, make for running project commands, docker for postgrest and auth test containers, and supabase-cli for storage and realtime test containers. It also notes that uv is "currently the only tool that understands the workspace setup", which is a concrete constraint rather than a preference: pip and Poetry do not resolve a uv workspace the same way. Each subpackage carries its own pyproject.toml and its own Makefile, and the root Makefile coordinates them. The data flow implied by the package names is conventional for a Supabase client: a request goes through the top-level supabase client, which delegates to postgrest for table operations, supabase_auth for identity, storage3 for object storage, supabase_functions for invoking edge functions, and realtime-py for the websocket subscription path. The README does not document the internal call graph, so I am reading the structure from the package list and the per-package README links rather than from a stated design document. What is documented is the test topology: postgrest and auth tests spin up docker containers, while storage and realtime tests need the supabase-cli. That tells you the test suite is integration-heavy for four of the six packages, which is a meaningful operational cost if you plan to run the suite locally.

Getting a working checkout: uv venv, uv sync, make ci

The README gives an explicit sequence for local development. Clone the repository, then create and activate a virtual environment with uv, then sync the workspace:

git clone https://github.com/supabase/supabase-py.git cd supabase-py uv venv supabase-py source supabase-py/bin/activate uv sync

The README recommends uv specifically because it is the only tool that understands the workspace layout, and it points to the uv docs on workspaces for background. If you have nix installed, the repository includes a flake.nix and the README says you may prefer to use nix develop instead; in that path the generated python executable is derived from the root pyproject.toml through uv2nix and should already have the workspace dependencies installed. For running tests, the root Makefile dispatches to each subpackage. The documented command is make ci, which internally issues make -C src/{package} tests for each package. The README also documents make ci -jN for parallel execution and warns that parallel runs scramble the CLI output, making error messages harder to parse. Three other root targets are documented: make install-hooks to install commit hooks into the local .git folder, make stop-infra to stop all running containers across packages, and make clean to delete intermediate test files. Subpackage commands are reachable from the root by prefixing with the package name, and the README gives make realtime.tests and make storage.clean as examples. Note that none of this is the install path for a consumer. If you are using the library rather than developing it, the relevant artefact is the supabase package on PyPI, and the README does not spell out a pip install line for it.

The integration test containers are the real cost of contributing

Four of the six subpackages cannot be tested with a plain Python environment. According to the README, postgrest and auth need docker containers, and storage and realtime need the supabase-cli. That means a contributor fixing a bug in storage3 has to have a Supabase CLI installation and a running local stack before make storage.tests will do anything useful. The nix shell in flake.nix bundles all four dependencies (uv, make, docker, supabase-cli), which is the intended shortcut, but it assumes you are willing to install nix. This is the clearest limitation in the repository as documented: the development loop has a heavier setup than a pure unit-test Python library, and the README does not describe a lighter path for running a single test file against mocks. The parallel test flag has a second, smaller cost. The README explicitly says -jN messes up CLI output and makes parsing error messages difficult, so the fast path and the debuggable path are in tension. For a contributor chasing a failing assertion, that trade-off is worth knowing before running make ci -j.

Where supabase-py is the wrong tool

If your application talks to a Postgres database you operate yourself and you do not use Supabase auth, storage, functions, or realtime, this library adds surface area you will not exercise. The postgrest subpackage speaks the PostgREST HTTP protocol, not the Postgres wire protocol. That distinction matters: a PostgREST client issues HTTP requests against a REST endpoint generated from your schema, while a driver like psycopg or an ORM like SQLAlchemy opens a direct Postgres connection and can run arbitrary SQL, manage transactions across multiple statements, use server-side cursors, and take advantage of the full type system. If your workload is bulk analytical inserts, long-running transactions, or anything that needs LISTEN/NOTIFY or advisory locks, a PostgREST-based client is the wrong layer. The README's own framing supports this reading: the links it offers are about OAuth login in Flask and loading data into Supabase, not about general database access from Python. There is also a versioning consideration. The release list shows v2.31.0, v2.30.1, and v2.30.0, with the two most recent minor and patch releases landing within a week of each other and the prior minor about three weeks before that. Frequent releases are normal for a client tracking a hosted platform, but they mean your dependency pinning strategy should be deliberate rather than floating.

The alternative is not another Supabase client, it is a different layer

The real comparison is between supabase-py and the components you would assemble without it. On the database side, psycopg (or asyncpg for asyncio code) connects straight to Postgres and gives you SQL, transactions, and prepared statements. SQLAlchemy adds a query builder and session management on top of that. Neither knows anything about Supabase auth tokens, storage buckets, or realtime channels, so you would implement those integrations yourself against the Supabase HTTP APIs. The difference in approach is protocol-level: supabase-py routes your queries through PostgREST over HTTP, which means every read and write is an HTTP request with the associated latency and connection overhead, while a direct driver keeps a persistent Postgres connection and lets you batch statements inside a transaction. For an application whose queries are small, row-level-secured, and driven by a logged-in user's identity, the PostgREST route is a reasonable fit and the token plumbing is already done for you. For an application that moves large volumes of data or needs multi-statement transactional guarantees, assembling psycopg plus a handful of HTTP calls for auth is more work up front and less friction later. The honest framing is that these are different tools for different access patterns, not competing implementations of the same thing.

Licence, maintenance, and what to verify before depending on it

The repository is MIT licensed, which permits commercial use, modification, and redistribution provided the copyright notice and permission notice are preserved. That is a permissive licence with few obligations, but it is worth confirming which licence file applies to each subpackage if you vendor one of them, since a monorepo can in principle carry per-package terms even when the root states MIT. I have not inspected the individual subpackage licence files, so treat that as something to check rather than something established here. On maintenance, the repository is not archived, the default branch is main, and the most recent push recorded is 2026-09-09. The release history shows a steady cadence through mid-2026. The README does not describe a deprecation policy, a supported Python version matrix, or a versioning contract for the subpackages relative to the umbrella supabase package, and those are the gaps that matter most for a production dependency. Before adopting, pin the exact subpackages you use rather than the umbrella package if you only need one capability, check the published version of that subpackage on PyPI against the source tree, and read the per-package README under src/ for the one you actually intend to call, because the root README is a map of the repository rather than a usage guide for any single library.

Editorial conclusion

Adopt supabase-py if your backend already lives on a Supabase project and you want auth, storage, functions, and realtime behind one Python dependency set; skip it if you only need SQL access to a Postgres instance you host yourself, because psycopg or SQLAlchemy will do that without pulling in the Supabase auth and realtime layers. Before committing, verify three things against your own project: that the subpackage you need (supabase_auth, storage3, postgrest, realtime-py, supabase_functions) is published at the version you require, that your Python version and dependency resolver can build the workspace the way the README describes with uv sync, and that the release cadence visible in the changelog matches your upgrade window, since the three most recent releases landed within roughly four months of each other.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. supabase/supabase-py on GitHub
Community notes

Community notes