Skip to content

feat: drop support for python 3.9 and 3.10 - #1915

Merged
spydon merged 2 commits into
mainfrom
chore/drop-python-3.9-3.10
Nov 3, 2026
Merged

spydon merged 2 commits into
mainfrom
chore/drop-python-3.9-3.10

Conversation

@spydon

@spydon spydon commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #1914.

Summary

Python 3.9 and 3.10 are past end of life, and the security fixes for most dependencies with open Dependabot alerts are only released for Python 3.10+ or 3.11+. Dropping both versions lets the lockfile resolve every package to a single patched version.

The PR has two commits so the hand-made changes can be reviewed separately from the mechanical ruff rewrite.

1. Drop Python 3.9 and 3.10

  • Require requires-python = ">=3.11" in every package and in the FastAPI example.
  • CI tests 3.11, 3.12, 3.13 and 3.14. The FastAPI e2e job tests 3.11 and 3.14.
  • Remove the "Python versions below 3.10 are deprecated" warnings and the version gates for StrEnum and Self.
  • Drop the strenum dependency from functions and postgrest.
  • Allow pytest 9 and pytest-asyncio 1.3+ in functions and supabase, so pytest gets its tmpdir fix.
  • Relock. Every package now resolves to one version, and every alert against the root uv.lock resolves to a patched version. pyarrow is held at 26.0.0 because 26.0.1 was published today without most of its wheels.
  • Update the devcontainers, READMEs and AGENTS.md.

2. Ruff pyupgrade fixes for py311

With target-version = "py311", ruff's keep-runtime-typing stops applying, so ruff check --fix rewrites Optional[X] and Union[X, Y] to X | None and X | Y across about 100 files, _sync included. The runtime Union aliases ruff has no fix for were converted by hand the same way. ASYNC109 is ignored because it only fires on py311+ and would require removing the public timeout parameters on the realtime channel methods.

Release note

This uses feat: rather than feat!: so release-please cuts a minor release instead of a major one on main. Users on 3.9 and 3.10 keep resolving the last compatible release, because pip and uv honour requires-python.

Testing

  • make mypy passes on Python 3.11, 3.12, 3.13 and 3.14.
  • make <pkg>.tests passes for all six packages on Python 3.11, including the infrastructure-backed suites (functions 121, supabase 50 plus xfail/xpass, postgrest 614, storage 151, auth 257, realtime 89).
  • make build-sync followed by make ruff produces no diff.

Summary by CodeRabbit

  • Compatibility

    • The minimum supported Python version is now 3.11 across the SDK packages and FastAPI example. Python 3.9 and 3.10 are no longer included in the main CI test matrix.
    • Development containers now use Python 3.11. CI continues to test through Python 3.14, with updated Python versions in the FastAPI end-to-end workflow.
  • Documentation

    • Updated installation guidance and prerequisites to specify Python 3.11 or later.

@spydon
spydon requested a review from o-santi as a code owner November 3, 2026 10:03
@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Walkthrough

The pull request raises the minimum supported Python version to 3.11 across the repository’s packages and updates CI, development containers, and documentation. It replaces legacy nullable and union annotations with native syntax and removes compatibility checks and fallbacks tied to older Python versions.

Changes: Python 3.11 Compatibility Update

Layer / File(s) Summary
Repository and example configuration
.devcontainer/*, .github/workflows/*, AGENTS.md, pyproject.toml, examples/fastapi/*
Repository guidance, CI matrices, devcontainers, Ruff settings, and the FastAPI example now specify Python 3.11. Example test annotations use native union syntax.
Auth package updates
src/auth/pyproject.toml, src/auth/src/supabase_auth/*, src/auth/scripts/*, src/auth/tests/*
Auth package metadata requires Python 3.11. APIs, public types, and tests use native union annotations; client runtime checks and warnings for Python versions below 3.10 are removed.
Functions package updates
src/functions/pyproject.toml, src/functions/src/supabase_functions/*, src/functions/tests/*
The package requires Python 3.11, removes the strenum fallback, and updates annotations. Its tests now check the standard-library StrEnum; pytest dependency lower bounds also change.
PostgREST package updates
src/postgrest/pyproject.toml, src/postgrest/README.md, src/postgrest/src/postgrest/*, src/postgrest/tests/*
The package requires Python 3.11, removes the strenum fallback and old-runtime warnings, and updates API, type, and test annotations.
Realtime package updates
src/realtime/pyproject.toml, src/realtime/src/realtime/*, src/realtime/tests/*
The package requires Python 3.11. Async and sync APIs, message types, and tests use native union annotations; the async client’s old-runtime warning is removed.
Storage package updates
src/storage/pyproject.toml, src/storage/src/storage3/*, src/storage/tests/*
The package requires Python 3.11. Async and sync APIs, types, exceptions, and tests use native union annotations; the sync and async client old-runtime warnings are removed.
Supabase facade updates
src/supabase/README.md, src/supabase/pyproject.toml, src/supabase/src/supabase/*
The facade requires Python 3.11 and updates its installation instructions, client options, and sync and async client annotations. The pytest-asyncio lower bound also changes.

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Other

Possibly related PRs

  • supabase/supabase-py#1917: Adds the Python support policy that describes version support and dropping end-of-life versions.

Suggested reviewers: hsusul

Merge Risk: Minimal · up to 42d8f

The Python 3.11 minimum is consistently reflected across packages and development configuration. No actionable merge-blocking issue is identified; merge after normal checks pass.

Pre-merge checks: Passed 4 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Docstring Coverage Inconclusive Docstring coverage is 35.14% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title "feat: drop support for python 3.9 and 3.10" matches the main change in the changeset. The raw summary shows the minimum Python version raised to 3.11 across packages, CI matrices, devcontai…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title "feat: drop support for python 3.9 and 3.10" matches the main change in the changeset. The raw summary shows the minimum Python version raised to 3.11 across packages, CI matrices, devcontainers, and docs. It also shows the removal of Python-version gates and the strenum dependency. The title is concise, specific, and free of file lists or vague wording. It also follows a conventional commit prefix.

Full details: Docstring Coverage

Explanation

Docstring coverage is 35.14% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 111 functions across 50 files. (53 skipped: 20 unsupported, 33 over the file limit.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between fc58953 and 42d8f97.

Files ignored due to path filters: 1
  • uv.lock is excluded by !**/*.lock
Files selected for processing: 103
  • .devcontainer/Dockerfile
  • .devcontainer/devcontainer.json
  • .github/workflows/ci.yml
  • .github/workflows/e2e-fastapi.yml
  • AGENTS.md
  • examples/fastapi/README.md
  • examples/fastapi/pyproject.toml
  • examples/fastapi/tests/e2e/test_engine_e2e.py
  • examples/fastapi/tests/test_dependencies.py
  • pyproject.toml
  • src/auth/.devcontainer/Dockerfile
  • src/auth/.devcontainer/devcontainer.json
  • src/auth/pyproject.toml
  • src/auth/scripts/gh-download.py
  • src/auth/src/supabase_auth/_async/gotrue_admin_api.py
  • src/auth/src/supabase_auth/_async/gotrue_admin_oauth_api.py
  • src/auth/src/supabase_auth/_async/gotrue_base_api.py
  • src/auth/src/supabase_auth/_async/gotrue_client.py
  • src/auth/src/supabase_auth/_async/storage.py
  • src/auth/src/supabase_auth/_sync/gotrue_admin_api.py
  • src/auth/src/supabase_auth/_sync/gotrue_admin_oauth_api.py
  • src/auth/src/supabase_auth/_sync/gotrue_base_api.py
  • src/auth/src/supabase_auth/_sync/gotrue_client.py
  • src/auth/src/supabase_auth/_sync/storage.py
  • src/auth/src/supabase_auth/errors.py
  • src/auth/src/supabase_auth/helpers.py
  • src/auth/src/supabase_auth/timer.py
  • src/auth/src/supabase_auth/types.py
  • src/auth/tests/_async/clients.py
  • src/auth/tests/_async/test_auto_refresh_tick.py
  • src/auth/tests/_async/test_gotrue.py
  • src/auth/tests/_async/test_subscriptions.py
  • src/auth/tests/_sync/clients.py
  • src/auth/tests/_sync/test_auto_refresh_tick.py
  • src/auth/tests/_sync/test_gotrue.py
  • src/auth/tests/_sync/test_subscriptions.py
  • src/auth/tests/test_auto_refresh.py
  • src/functions/pyproject.toml
  • src/functions/src/supabase_functions/__init__.py
  • src/functions/src/supabase_functions/_async/functions_client.py
  • src/functions/src/supabase_functions/_sync/functions_client.py
  • src/functions/src/supabase_functions/utils.py
  • src/functions/tests/test_client.py
  • src/functions/tests/test_errors.py
  • src/functions/tests/test_utils.py
  • src/postgrest/.devcontainer/Dockerfile
  • src/postgrest/.devcontainer/devcontainer.json
  • src/postgrest/README.md
  • src/postgrest/pyproject.toml
  • src/postgrest/src/postgrest/_async/client.py
  • src/postgrest/src/postgrest/_async/request_builder.py
  • src/postgrest/src/postgrest/_sync/client.py
  • src/postgrest/src/postgrest/_sync/request_builder.py
  • src/postgrest/src/postgrest/base_client.py
  • src/postgrest/src/postgrest/base_request_builder.py
  • src/postgrest/src/postgrest/exceptions.py
  • src/postgrest/src/postgrest/types.py
  • src/postgrest/tests/_async/test_request_builder.py
  • src/postgrest/tests/_sync/test_request_builder.py
  • src/postgrest/tests/test_auth_switch.py
  • src/postgrest/tests/test_max_affected.py
  • src/realtime/pyproject.toml
  • src/realtime/src/realtime/_async/channel.py
  • src/realtime/src/realtime/_async/client.py
  • src/realtime/src/realtime/_async/presence.py
  • src/realtime/src/realtime/_async/push.py
  • src/realtime/src/realtime/_async/timer.py
  • src/realtime/src/realtime/_sync/channel.py
  • src/realtime/src/realtime/_sync/client.py
  • src/realtime/src/realtime/_sync/presence.py
  • src/realtime/src/realtime/exceptions.py
  • src/realtime/src/realtime/message.py
  • src/realtime/src/realtime/types.py
  • src/realtime/tests/test_connection.py
  • src/realtime/tests/test_http_send.py
  • src/realtime/tests/test_subscription_status.py
  • src/storage/pyproject.toml
  • src/storage/src/storage3/__init__.py
  • src/storage/src/storage3/_async/analytics.py
  • src/storage/src/storage3/_async/bucket.py
  • src/storage/src/storage3/_async/client.py
  • src/storage/src/storage3/_async/file_api.py
  • src/storage/src/storage3/_async/request.py
  • src/storage/src/storage3/_async/vectors.py
  • src/storage/src/storage3/_sync/analytics.py
  • src/storage/src/storage3/_sync/bucket.py
  • src/storage/src/storage3/_sync/client.py
  • src/storage/src/storage3/_sync/file_api.py
  • src/storage/src/storage3/_sync/request.py
  • src/storage/src/storage3/_sync/vectors.py
  • src/storage/src/storage3/exceptions.py
  • src/storage/src/storage3/types.py
  • src/storage/tests/_async/test_client.py
  • src/storage/tests/_sync/test_client.py
  • src/storage/tests/test_vector_index.py
  • src/storage/tests/utils.py
  • src/supabase/README.md
  • src/supabase/pyproject.toml
  • src/supabase/src/supabase/_async/auth_client.py
  • src/supabase/src/supabase/_async/client.py
  • src/supabase/src/supabase/_sync/auth_client.py
  • src/supabase/src/supabase/_sync/client.py
  • src/supabase/src/supabase/lib/client_options.py

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 4 remain after this review.

Base automatically changed from chore/refresh-lockfiles to main November 3, 2026 10:26
Python 3.9 and 3.10 are past end of life, and the security fixes for most dependencies with open Dependabot alerts are only released for Python 3.10+ or 3.11+.

- Require Python >=3.11 in every package and the FastAPI example, and test 3.11 to 3.14 in CI.
- Remove the Python <3.10 deprecation warnings and the version gates for StrEnum and Self.
- Drop the strenum dependency from functions and postgrest.
- Allow pytest 9 and pytest-asyncio 1.3+ in functions and supabase, so pytest gets its tmpdir fix.
- Relock, which collapses the per-Python-version forks onto the patched releases.
Raising the ruff target to py311 makes keep-runtime-typing stop applying, so ruff now rewrites Optional and Union to PEP 604 unions everywhere. All changes are from ruff check --fix, apart from the runtime Union aliases ruff has no fix for, which are converted by hand the same way.

ASYNC109 is ignored because it only fires on py311+ and would require removing the public timeout parameters of the realtime channel methods.
@spydon
spydon force-pushed the chore/drop-python-3.9-3.10 branch from d18f511 to 42d8f97 Compare November 3, 2026 10:28
@spydon
spydon merged commit 37786ed into main Nov 3, 2026
38 checks passed
@spydon
spydon deleted the chore/drop-python-3.9-3.10 branch November 3, 2026 10:38
spydon added a commit that referenced this pull request Nov 3, 2026
Follows #1915.

## Summary

- Add Python 3.15 to the `ci.yml` test matrix and the FastAPI e2e
matrix.
- Bump the uv pinned in CI from 0.8.2 to 0.13.3. uv 0.8.2 predates
Python 3.15 and cannot install it.
- Upgrade the locked packages that had no 3.15 wheels: pydantic 2.14.2
and pydantic-core 2.50.2 (pydantic-core 2.41 cannot build for 3.15
because its PyO3 stops at 3.14), pyiceberg 0.12.0, pyroaring,
markupsafe, mmh3 and cffi.
- pydantic 2.14 no longer lets mypy infer the type of a module-level
`TypeAdapter`, so annotate the five that need it in auth and storage,
using the `Name: TypeAdapter[T] = TypeAdapter(T)` pattern already used
elsewhere.
- Update `AGENTS.md`.

pyiceberg 0.12 moves `pyiceberg-core` out of the `pyarrow` extra into
its own extra. storage only uses `PyArrowFileIO`, and the storage tests
pass.

## Testing

- `make mypy` passes on Python 3.11 and 3.15.
- On Python 3.15 locally: functions, supabase, postgrest, storage and
auth pass. The full infrastructure-backed suites are left to CI.
spydon pushed a commit that referenced this pull request Nov 3, 2026
🤖 I have created a release *beep* *boop*
---


##
[2.34.0](v2.33.0...v2.34.0)
(2026-11-03)


### Features

* drop support for python 3.9 and 3.10
([#1915](#1915))
([37786ed](37786ed))
* **examples:** add FastAPI Realtime Rule Engine example
([#1519](#1519))
([6449e1e](6449e1e))
* **postgrest:** add client-level retry toggle
([#1900](#1900))
([e1916b5](e1916b5)),
closes [#1561](#1561)
* **postgrest:** add strip_nulls()
([#1760](#1760))
([c86ec9f](c86ec9f))
* **realtime:** add explicit REST API call for broadcast
([#1256](#1256))
([deec947](deec947))


### Bug Fixes

* **auth:** accept oauth clients without a name
([#1830](#1830))
([936458e](936458e))
* **auth:** accept pending secure email confirmations
([#1845](#1845))
([1e0c262](1e0c262))
* **auth:** avoid cancelling the running refresh callback
([#1716](#1716))
([606e0ac](606e0ac))
* **auth:** copy query_params in link_identity
([#1879](#1879))
([36e9952](36e9952))
* **auth:** emit PASSWORD_RECOVERY from verify_otp
([#1743](#1743))
([b571cc2](b571cc2))
* **auth:** emit SIGNED_IN when set_session keeps a valid token
([#1749](#1749))
([9c092db](9c092db))
* **auth:** handle empty OAuth client lists
([#1736](#1736))
([7d68e6b](7d68e6b))
* **auth:** keep existing session in sign-up and sign-in methods
([#1935](#1935))
([c3fa0f1](c3fa0f1))
* **auth:** keep existing session when verify_otp does not return one
([#1933](#1933))
([cae942d](cae942d))
* **auth:** keep expired session in initialize_from_storage when auto
refresh is off
([#1938](#1938))
([1436832](1436832))
* **auth:** keep or clear the session by scope when sign out fails
([#1824](#1824))
([de9932e](de9932e))
* **auth:** make code_verifier optional in CodeExchangeParams
([#1922](#1922))
([0b1d490](0b1d490))
* **auth:** map httpx transport errors to AuthRetryableError
([#1808](#1808))
([901f00d](901f00d))
* **auth:** normalize trailing slash in base URL
([#1766](#1766))
([de040ec](de040ec))
* **auth:** preserve phone numbers in MFA factor responses
([#1837](#1837))
([0e1cf4c](0e1cf4c))
* **auth:** preserve the PKCE recovery event
([#1906](#1906))
([cd0c4a3](cd0c4a3))
* **auth:** preserve the server error message on retryable 5xx responses
([#1833](#1833))
([c1727d5](c1727d5))
* **auth:** raise AuthInvalidJwtError for malformed JWTs in get_claims
([#1871](#1871))
([1aa8090](1aa8090))
* **auth:** raise AuthInvalidJwtError for malformed tokens in
set_session
([#1920](#1920))
([301ce7d](301ce7d))
* **auth:** read implicit grant params from the url fragment
([#1923](#1923))
([de2c6fc](de2c6fc))
* **auth:** require pyjwt&gt;=2.15.1 for security fixes
([#1820](#1820))
([f41e80e](f41e80e))
* **auth:** send one refresh request per auto-refresh tick
([#1854](#1854))
([bc29bc6](bc29bc6))
* **auth:** send PKCE challenges for email and SSO flows
([#1682](#1682))
([66cd7ee](66cd7ee))
* **auth:** stop the admin API from sharing the client's header dict
([#1645](#1645))
([6b53131](6b53131))
* **auth:** use inspect.iscoroutinefunction in Timer
([#1875](#1875))
([4d5d430](4d5d430))
* **auth:** validate session and mfa enroll response after field
validation
([#1904](#1904))
([0310467](0310467))
* **functions:** drop the apiKey header on cross host redirects
([#1885](#1885))
([268557a](268557a))
* **functions:** keep the query string when invoking a function
([#1816](#1816))
([685469c](685469c))
* make the capability matrix verifiable
([#1867](#1867))
([804e7e2](804e7e2))
* **postgrest:** accept generated typeddict types in insert, upsert and
update ([#1939](#1939))
([1ae57b8](1ae57b8))
* **postgrest:** apply normalized timeout to internal httpx clients
([#1758](#1758))
([774e996](774e996))
* **postgrest:** clear basic auth when selecting bearer auth
([#1713](#1713))
([32e748b](32e748b))
* **postgrest:** describe non-JSON error responses with the decoded body
and a string code
([#1912](#1912))
([dd75df1](dd75df1))
* **postgrest:** drop pydantic v1 compat layer and align pydantic floor
([#1902](#1902))
([8ddd531](8ddd531))
* **postgrest:** escape quotes and backslashes in bulk column names
([#1948](#1948))
([7bebdeb](7bebdeb))
* **postgrest:** json-encode dictionary rpc arguments in get and head
requests ([#1899](#1899))
([86da454](86da454)),
closes [#1847](#1847)
* **postgrest:** keep the http client and basic auth in schema()
([#1672](#1672))
([c4e440c](c4e440c))
* **postgrest:** make APIError fields optional so partial error bodies
keep their message
([#1732](#1732))
([18bd628](18bd628))
* **postgrest:** omit columns for empty bulk inserts and upserts
([#1815](#1815))
([62a4e4d](62a4e4d))
* **postgrest:** preserve chaining after text search
([#1708](#1708))
([9588283](9588283))
* **postgrest:** preserve injected HTTPX client authentication
([#1838](#1838))
([79d14d9](79d14d9))
* **postgrest:** quote rpc array elements sent on GET and HEAD
([#1762](#1762))
([1bb870e](1bb870e))
* **postgrest:** raise on a non-http base_url
([#1881](#1881))
([610875d](610875d))
* **postgrest:** read the Proxy-Status error code when an error response
has no body
([#1621](#1621))
([34227d1](34227d1))
* **postgrest:** replace conflicting max-affected preferences
([#1827](#1827))
([5f989e1](5f989e1))
* **postgrest:** retry GET and HEAD requests on network errors
([#1777](#1777))
([1113f40](1113f40))
* **postgrest:** return no count when the total is unknown
([#1892](#1892))
([3c21359](3c21359))
* **postgrest:** send rpc list args as array literals on GET and HEAD
([#1752](#1752))
([50e7a4c](50e7a4c))
* **postgrest:** serialize null and booleans in in_() like other filters
([#1863](#1863))
([2cc0e03](2cc0e03))
* preserve functions timeout when replacing client options
([#1722](#1722))
([7fac036](7fac036))
* **realtime:** accept postgres change error arrays
([#1908](#1908))
([9c59f9a](9c59f9a))
* **realtime:** call late timeout handlers without a payload
([#1831](#1831))
([b6ddb74](b6ddb74))
* **realtime:** cap reconnect backoff at 60 seconds
([#1768](#1768))
([23ddbca](23ddbca))
* **realtime:** default postgres_changes schema to public
([#1884](#1884))
([a6e562d](a6e562d))
* **realtime:** deliver every broadcast to "*" listeners, ignoring case
([#1818](#1818))
([eae2838](eae2838))
* **realtime:** deprecate channel.join() and route it through subscribe
([#1928](#1928))
([8ac936c](8ac936c))
* **realtime:** honor the WebSocket opening timeout
([#1839](#1839))
([46efa11](46efa11))
* **realtime:** keep postgres bindings and report mismatches on join
replies ([#1929](#1929))
([cfb2159](cfb2159))
* **realtime:** keep references to background tasks
([#1888](#1888))
([f959593](f959593))
* **realtime:** keep the replacement channel when the old one closes
([#1877](#1877))
([af1d15d](af1d15d))
* **realtime:** notify subscribers of channel errors and closure
([#1846](#1846))
([bcecfc3](bcecfc3))
* **realtime:** reconnect when the server closes the socket normally
([#1675](#1675))
([4dafafd](4dafafd))
* **realtime:** redact api key and access tokens from debug logs
([#1750](#1750))
([17147f2](17147f2))
* **realtime:** rejoin channels on the stepped schedule
([#1916](#1916))
([db14ec5](db14ec5))
* **realtime:** rejoin the channel after a presence callback is added
while joined
([#1686](#1686))
([697170c](697170c))
* **realtime:** report CHANNEL_ERROR to subscribers when the connection
drops ([#1897](#1897))
([a00d1aa](a00d1aa))
* **realtime:** restart timeout after resending push
([#1654](#1654))
([da3a353](da3a353))
* **realtime:** serialize initial websocket handshakes
([#1853](#1853))
([c5150d6](c5150d6))
* **realtime:** use the client timeout for join and leave pushes
([#1685](#1685))
([198396d](198396d))
* **realtime:** wait for the join reply in subscribe
([#1940](#1940))
([c725015](c725015))
* **storage:** accept field names in MetadataConfiguration
([#1921](#1921))
([e0b5716](e0b5716))
* **storage:** allow null metadata in list_v2
([#1804](#1804))
([9d2f19c](9d2f19c))
* **storage:** close the upload handle we opened, and only that one
([#1607](#1607))
([2f3bf40](2f3bf40))
* **storage:** install the iceberg file backend
([#1873](#1873))
([b2cbf04](b2cbf04))
* **storage:** let upload headers override the client's headers
([#1942](#1942))
([09855c3](09855c3))
* **storage:** merge a partial sortBy with the default in list
([#1817](#1817))
([3fb5620](3fb5620))
* **storage:** parse analytics bucket error responses
([#1894](#1894))
([c5d0149](c5d0149))
* **storage:** read object info in exists() so auth and bucket errors
raise ([#1825](#1825))
([980ac9f](980ac9f))
* **storage:** require topK in vector index query
([#1946](#1946))
([a60e0d2](a60e0d2))
* **storage:** stop create_client from emitting the timeout deprecation
warning ([#1919](#1919))
([3349ad8](3349ad8))
* **supabase:** keep postgrest and storage timeouts in replace()
([#1809](#1809))
([795cad4](795cad4))
* **supabase:** keep the session token on every auth event that has one
([#1856](#1856))
([ca2fb99](ca2fb99))
* **supabase:** reject non-string url and key in create_client
([#1926](#1926))
([030cbc9](030cbc9))
* **supabase:** replace() preserves postgrest and storage timeouts
([#1840](#1840))
([772ee24](772ee24))


### Performance Improvements

* **postgrest:** speed up JSON parsing by 22x using json.loads
([#1571](#1571))
([c56c5bb](c56c5bb))


### Documentation

* add support policy
([#1917](#1917))
([f1392d4](f1392d4))
* Clarify when get_user() returns None
([#1569](#1569))
([3d8417f](3d8417f))
* document SDK compatibility with Supabase services
([#1870](#1870))
([1ff1e4a](1ff1e4a))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: supabase-py-releaser[bot] <254608689+supabase-py-releaser[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants