Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.203.0/containers/python-3/.devcontainer/base.Dockerfile

# [Choice] Python version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.10, 3.9, 3.8, 3.7, 3.6, 3-bullseye, 3.10-bullseye, 3.9-bullseye, 3.8-bullseye, 3.7-bullseye, 3.6-bullseye, 3-buster, 3.10-buster, 3.9-buster, 3.8-buster, 3.7-buster, 3.6-buster
ARG VARIANT="3.10-bullseye"
ARG VARIANT="3.11-bullseye"
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}

# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
Expand Down
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// Update 'VARIANT' to pick a Python version: 3, 3.10, 3.9, 3.8, 3.7, 3.6
// Append -bullseye or -buster to pin to an OS version.
// Use -bullseye variants on local on arm64/Apple Silicon.
"VARIANT": "3.10-bullseye",
"VARIANT": "3.11-bullseye",
// Options
"NODE_VERSION": "lts/*"
}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
python-version: ["3.11", "3.12", "3.13", "3.14"]
package: ["functions", "realtime", "storage", "auth", "postgrest", "supabase"]
runs-on: ${{ matrix.os }}
timeout-minutes: 20
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/e2e-fastapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.12"]
python-version: ["3.11", "3.14"]

steps:
- name: Clone Repository
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Setup and commands: [README.md § Local Development](README.md#local-development

- `make <pkg>.tests` runs mypy and pytest. For `auth`, `postgrest`, `storage` and `realtime`, pytest first starts Docker / Supabase CLI infra; `make stop-infra` when done.
- Fast loop for tests that need no infra: from `src/<pkg>`, `uv run --frozen --package <import name> pytest tests/<file>.py`.
- Code must run on Python 3.9 — CI tests 3.9–3.14 ([ci.yml](.github/workflows/ci.yml)).
- Code must run on Python 3.11 — CI tests 3.11–3.14 ([ci.yml](.github/workflows/ci.yml)).

## Public API

Expand Down
2 changes: 1 addition & 1 deletion examples/fastapi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ JS client and shows a live event feed.
- A Supabase project (create one free at supabase.com)
- uv installed (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
- Supabase CLI installed (`brew install supabase/tap/supabase`)
- Python 3.10+
- Python 3.11+

## Setup

Expand Down
2 changes: 1 addition & 1 deletion examples/fastapi/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "fastapi-realtime-rule-engine"
version = "0.1.0"
description = "FastAPI Realtime Rule Engine example using supabase-py"
requires-python = ">=3.9"
requires-python = ">=3.11"
dependencies = [
"fastapi>=0.110.0",
"uvicorn[standard]>=0.27.0",
Expand Down
3 changes: 1 addition & 2 deletions examples/fastapi/tests/e2e/test_engine_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"""

import asyncio
from typing import Optional

_POLL_INTERVAL = 0.5
_TIMEOUT = 45
Expand All @@ -24,7 +23,7 @@

async def _wait_for_rule_event(
service_client, rule_id: str, task_id: str, timeout: float = _TIMEOUT
) -> Optional[dict]:
) -> dict | None:
deadline = asyncio.get_running_loop().time() + timeout
while asyncio.get_running_loop().time() < deadline:
result = (
Expand Down
3 changes: 1 addition & 2 deletions examples/fastapi/tests/test_dependencies.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from typing import Optional
from unittest.mock import AsyncMock, patch

import pytest
from fastapi import HTTPException
from starlette.requests import Request


def _make_request(auth_header: Optional[str]) -> Request:
def _make_request(auth_header: str | None) -> Request:
scope = {
"type": "http",
"method": "GET",
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ supabase = { workspace = true }
asyncio_mode = "auto"

[tool.ruff]
target-version = "py39"
target-version = "py311"

[tool.ruff.lint]
select = [
Expand Down Expand Up @@ -61,7 +61,7 @@ select = [
# flake8-async
"ASYNC",
]
ignore = ["F403", "E501", "E402", "ASYNC230"]
ignore = ["F403", "E501", "E402", "ASYNC230", "ASYNC109"]

[tool.ruff.lint.per-file-ignores]
# FastAPI uses Depends() in function default arguments — B008 is intentional there.
Expand Down
2 changes: 1 addition & 1 deletion src/auth/.devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.203.0/containers/python-3/.devcontainer/base.Dockerfile

# [Choice] Python version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.10, 3.9, 3.8, 3.7, 3.6, 3-bullseye, 3.10-bullseye, 3.9-bullseye, 3.8-bullseye, 3.7-bullseye, 3.6-bullseye, 3-buster, 3.10-buster, 3.9-buster, 3.8-buster, 3.7-buster, 3.6-buster
ARG VARIANT="3.10-bullseye"
ARG VARIANT="3.11-bullseye"
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}

# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
Expand Down
2 changes: 1 addition & 1 deletion src/auth/.devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// Update 'VARIANT' to pick a Python version: 3, 3.10, 3.9, 3.8, 3.7, 3.6
// Append -bullseye or -buster to pin to an OS version.
// Use -bullseye variants on local on arm64/Apple Silicon.
"VARIANT": "3.10-bullseye",
"VARIANT": "3.11-bullseye",
// Options
"NODE_VERSION": "lts/*"
}
Expand Down
2 changes: 1 addition & 1 deletion src/auth/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ classifiers = [
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
requires-python = ">=3.9"
requires-python = ">=3.11"
dependencies = [
"httpx[http2] >=0.26,<0.29",
"pydantic >=2.11.7,<3",
Expand Down
7 changes: 3 additions & 4 deletions src/auth/scripts/gh-download.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import os
import shutil
import sys
from typing import Optional

from github import Github, GithubException
from github.ContentFile import ContentFile
Expand Down Expand Up @@ -90,9 +89,9 @@ def main(argv) -> None:
print(err)
usage()
sys.exit(2)
repo: Optional[str] = None
branch: Optional[str] = None
folder: Optional[str] = None
repo: str | None = None
branch: str | None = None
folder: str | None = None
for opt, arg in opts:
if opt in ("-r", "--repo"):
repo = arg
Expand Down
12 changes: 5 additions & 7 deletions src/auth/src/supabase_auth/_async/gotrue_admin_api.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from __future__ import annotations

from typing import Optional

from httpx import AsyncClient, QueryParams

from ..helpers import (
Expand Down Expand Up @@ -40,10 +38,10 @@ def __init__(
self,
*,
url: str = "",
headers: Optional[dict[str, str]] = None,
http_client: Optional[AsyncClient] = None,
headers: dict[str, str] | None = None,
http_client: AsyncClient | None = None,
verify: bool = True,
proxy: Optional[str] = None,
proxy: str | None = None,
) -> None:
http_headers = headers or {}
AsyncGoTrueBaseAPI.__init__(
Expand Down Expand Up @@ -81,7 +79,7 @@ async def sign_out(self, jwt: str, scope: SignOutScope = "global") -> None:
async def invite_user_by_email(
self,
email: str,
options: Optional[InviteUserByEmailOptions] = None,
options: InviteUserByEmailOptions | None = None,
) -> UserResponse:
"""
Sends an invite link to an email address.
Expand Down Expand Up @@ -131,7 +129,7 @@ async def create_user(self, attributes: AdminUserAttributes) -> UserResponse:
return parse_user_response(response)

async def list_users(
self, page: Optional[int] = None, per_page: Optional[int] = None
self, page: int | None = None, per_page: int | None = None
) -> list[User]:
"""
Get a list of users.
Expand Down
4 changes: 1 addition & 3 deletions src/auth/src/supabase_auth/_async/gotrue_admin_oauth_api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import Optional

from ..types import (
CreateOAuthClientParams,
OAuthClientListResponse,
Expand All @@ -17,7 +15,7 @@ class AsyncGoTrueAdminOAuthAPI:

async def list_clients(
self,
params: Optional[PageParams] = None,
params: PageParams | None = None,
) -> OAuthClientListResponse:
"""
Lists all OAuth clients with optional pagination.
Expand Down
17 changes: 8 additions & 9 deletions src/auth/src/supabase_auth/_async/gotrue_base_api.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from __future__ import annotations

from typing import Any, Optional
from typing import Any, Literal, Self

from httpx import AsyncClient, HTTPStatusError, QueryParams, RequestError, Response
from pydantic import BaseModel
from typing_extensions import Literal, Self

from ..constants import API_VERSION_HEADER_NAME, API_VERSIONS_2024_01_01_NAME
from ..helpers import handle_exception
Expand All @@ -16,9 +15,9 @@ def __init__(
*,
url: str,
headers: dict[str, str],
http_client: Optional[AsyncClient],
http_client: AsyncClient | None,
verify: bool = True,
proxy: Optional[str] = None,
proxy: str | None = None,
) -> None:
self._url = url.rstrip("/")
# Copy: callers pass a dict they keep mutating, and GoTrueClient hands
Expand Down Expand Up @@ -47,11 +46,11 @@ async def _request(
method: Literal["GET", "OPTIONS", "HEAD", "POST", "PUT", "PATCH", "DELETE"],
path: str,
*,
jwt: Optional[str] = None,
redirect_to: Optional[str] = None,
headers: Optional[dict[str, str]] = None,
query: Optional[QueryParams] = None,
body: Optional[Any] = None,
jwt: str | None = None,
redirect_to: str | None = None,
headers: dict[str, str] | None = None,
query: QueryParams | None = None,
body: Any | None = None,
no_resolve_json: bool = False,
) -> Response:
url = f"{self._url}/{path}"
Expand Down
Loading
Loading