Learning · · 5 min read
A Simple Guide to Using Supabase Edge Functions with Python
I walk through what Supabase Edge Functions are, how to set them up for a Python project, and how I tied them into my chatbot – all with honest notes on what worked and what didn’t.
When I first heard about Supabase Edge Functions, I wondered if they could replace a tiny Flask server I was using for background tasks. The short answer is yes, and the longer answer is that they let you run lightweight code close to your database without managing a separate host. In this post I’ll show you how to use Supabase Edge Functions python, step by step, using only free tiers and the tools I already have on my laptop. If you’ve followed my guide on setting up a Python AI development environment, you’ll find the flow familiar – the only new piece is the Edge Function workflow.
What are Supabase Edge Functions and why use them
Supabase Edge Functions are serverless functions that run on the edge network, meaning they execute close to the user and have low latency. They are written in JavaScript or TypeScript by default, but Supabase recently added support for custom runtimes, letting you run Python code through a Docker‑based environment. The biggest benefit for me is that I can keep the code that talks to my database, sends emails, or processes a Gemini embedding in one place, without spinning up a full‑blown VM. This also means the cost stays at zero on the free tier, as long as the function stays lightweight.
how to use supabase edge functions python
The first thing I did was create a new Supabase project (if you already have one, you can skip this step). Once the project was ready, I enabled Edge Functions in the dashboard and installed the Supabase CLI on my machine. The CLI gives you a local dev server that mimics the edge environment, so you can test your code before deploying.
- Install the CLI: `npm install -g supabase` (requires Node, which I already use for VS Code extensions).
- Log in to your Supabase account: `supabase login` and follow the browser prompt.
- Create a new function directory: `supabase functions new my‑python‑fn` – this scaffolds a folder with a `Dockerfile` ready for Python.
- Edit the `Dockerfile` to use a Python base image, e.g., `FROM python:3.11-slim` and copy your `requirements.txt`.
- Write your Python code in `index.py`. A minimal example is shown later.
- Test locally with `supabase functions serve my‑python‑fn` – the CLI will expose the function at `http://localhost:54321/functions/v1/my‑python‑fn`.
- Deploy with `supabase functions deploy my‑python‑fn`. After a few seconds, the function is live at `https://<project>.supabase.co/functions/v1/my‑python‑fn`.
Writing your first edge function in python
I wanted the function to receive a short text prompt, generate an embedding with Gemini, and store it in a Supabase table. The code below does exactly that. I keep the logic tiny because the edge environment has a timeout of a few seconds.
import os
from fastapi import FastAPI, Request
from supabase import create_client, Client
from google.cloud import aiplatform
app = FastAPI()
# Initialise Supabase client – the URL and anon key are injected as env vars by Supabase
supabase: Client = create_client(os.getenv('SUPABASE_URL'), os.getenv('SUPABASE_ANON_KEY'))
# Initialise Gemini (or any model you prefer)
aiplatform.init(project=os.getenv('GCP_PROJECT'))
model = aiplatform.Model(model_name='gemini-1.0-pro')
@app.post('/')
async def embed(request: Request):
data = await request.json()
text = data.get('text', '')
if not text:
return {'error': 'No text provided'}
# Generate embedding using Gemini
embedding = model.predict([text])[0]
# Store in Supabase
resp = supabase.table('embeddings').insert({
'text': text,
'vector': embedding
}).execute()
return {'status': 'ok', 'data': resp.data}
Calling the edge function from my chatbot
In the Python chatbot I built earlier (see my post on adding email notifications to my Python chatbot), I added a small helper that POSTs the user’s query to the edge function and receives the stored embedding. The request is just a standard `requests.post` call, and because the function lives on Supabase’s CDN, the round‑trip is fast even on a 4G connection in Pundri.
import requests
def get_embedding(text: str) -> dict:
url = 'https://<project>.supabase.co/functions/v1/my-python-fn'
resp = requests.post(url, json={'text': text})
if resp.ok:
return resp.json()
else:
print('Edge function error:', resp.text)
return {}
Common pitfalls and how I fixed them
- Missing environment variables – Supabase injects `SUPABASE_URL` and `SUPABASE_ANON_KEY` only at runtime. I added a `.env` file locally and used `supabase functions serve --env-file .env` to mimic the production env.
- Cold start latency – the first request after a period of inactivity can take a few seconds. I mitigated this by adding a tiny “keep‑alive” cron job that pings the function every 10 minutes.
- Python dependencies not found – the Dockerfile must copy `requirements.txt` before `pip install`. Forgetting the order caused a build error that the CLI reported clearly.
- Embedding size limits – Supabase tables have a row size limit. I stored the vector as a JSON array after rounding to three decimal places, which reduced the payload dramatically.
Takeaway
Using Supabase Edge Functions python gave me a cheap, low‑maintenance way to run code that sits between my chatbot and the database. The workflow is simple enough that anyone with a laptop, VS Code, and a free Supabase account can try it. I still prefer a full Flask app for heavy processing, but for quick look‑ups, embeddings, or email triggers the edge functions are perfect. If you want to see the whole pipeline in action, check out my guide on adding email notifications to my Python chatbot and the post about adding vector search with Supabase, then give this edge‑function approach a spin. For more of my experiments, explore my projects.
If you want to keep reading, I also wrote about Setting up a Python AI Development Environment: My Simple Guide and Python, C and C++: what each one taught me.
Frequently asked questions
Do Supabase Edge Functions support Python out of the box?
Supabase ships with JavaScript runtimes by default, but you can run Python by providing a custom Dockerfile. The CLI builds the image for you, and once deployed the function behaves like any other edge function.
Can I store large vectors in Supabase tables?
Yes, but each row has a size limit. It helps to truncate the vector precision or store it as a compressed JSON string. I round to three decimal places and it fits comfortably.
How do I test an edge function locally before deploying?
The Supabase CLI offers `supabase functions serve <name>` which runs the function on your machine at a local URL. This mirrors the edge environment and lets you debug with standard tools like breakpoints or print statements.
What is the cost of using Supabase Edge Functions on the free tier?
The free tier includes a generous amount of invocations and compute time. As long as your function stays lightweight and you stay within the limits (a few hundred thousand calls per month), you won’t incur any charges.