Skip to content

Commit 20b7130

Browse files
authored
chore: include functions-py into monorepo (#1204)
1 parent a49b91b commit 20b7130

30 files changed

+2654
-35
lines changed

.release-please-manifest.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
22
"src/supabase": "2.18.1",
3-
"src/realtime": "2.7.0"
3+
"src/realtime": "2.7.0",
4+
"src/functions": "0.10.1"
45
}

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
.PHONY: ci, default, pre-commit
22

33
default:
4-
@echo "Available targets are: ci, pre-commit"
4+
@echo "Available targets are: ci, pre-commit, publish"
55

66
ci: pre-commit
77
make -C src/realtime tests
8+
make -C src/functions tests
89
make -C src/supabase tests
910

1011
publish:
1112
uv build --project realtime
1213
uv build --project supabase
14+
uv build --project functions
1315
uv publish
1416

1517
pre-commit:

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
[tool.uv.workspace]
22
members = [
33
"src/realtime",
4+
"src/functions",
45
"src/supabase"
56
]
67

78
[tool.uv.sources]
89
realtime = { workspace = true }
10+
supabase_functions = { workspace = true }
911
supabase = { workspace = true }
1012

1113
[tool.pytest.ini_options]

release-please-config.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@
55
"changelog-path": "src/realtime/CHANGELOG.md",
66
"release-type": "python"
77
},
8+
"src/functions": {
9+
"changelog-path": "src/functions/CHANGELOG.md",
10+
"release-type": "python"
11+
}
812
"src/supabase": {
913
"changelog-path": "src/supabase/CHANGELOG.md",
1014
"release-type": "python"
11-
}
15+
},
1216
}
1317
}

src/functions/CHANGELOG.md

Lines changed: 574 additions & 0 deletions
Large diffs are not rendered by default.

src/functions/Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests: pytest
2+
3+
pytest:
4+
uv run --package supabase_functions pytest --cov=./ --cov-report=xml --cov-report=html -vv
5+
6+
unasync:
7+
uv run --package supabase_functions run-unasync.py
8+
9+
build-sync: unasync
10+
sed -i '0,/SyncMock, /{s/SyncMock, //}' tests/_sync/test_function_client.py
11+
sed -i 's/SyncMock/Mock/g' tests/_sync/test_function_client.py
12+
sed -i 's/SyncClient/Client/g' src/supabase_functions/_sync/functions_client.py tests/_sync/test_function_client.py

src/functions/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Functions-py
2+
3+
4+
## Installation
5+
6+
`pip3 install supabase_functions`
7+
8+
## Usage
9+
10+
Deploy your function as per documentation.
11+
12+
13+
```python3
14+
import asyncio
15+
from supabase_functions import AsyncFunctionsClient
16+
async def run_func():
17+
fc = AsyncFunctionsClient("https://<project_ref>.functions.supabase.co", {})
18+
res = await fc.invoke("payment-sheet", {"responseType": "json"})
19+
20+
if __name__ == "__main__":
21+
asyncio.run(run_func())
22+
```

src/functions/conftest.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from typing import Dict, Tuple
2+
3+
import pytest
4+
5+
# store history of failures per test class name and per index
6+
# in parametrize (if parametrize used)
7+
_test_failed_incremental: Dict[str, Dict[Tuple[int, ...], str]] = {}
8+
9+
10+
def pytest_runtest_makereport(item, call):
11+
if "incremental" in item.keywords:
12+
# incremental marker is used
13+
if call.excinfo is not None:
14+
# the test has failed
15+
# retrieve the class name of the test
16+
cls_name = str(item.cls)
17+
# retrieve the index of the test (if parametrize is used
18+
# in combination with incremental)
19+
parametrize_index = (
20+
tuple(item.callspec.indices.values())
21+
if hasattr(item, "callspec")
22+
else ()
23+
)
24+
# retrieve the name of the test function
25+
test_name = item.originalname or item.name
26+
# store in _test_failed_incremental the original name of the failed test
27+
_test_failed_incremental.setdefault(cls_name, {}).setdefault(
28+
parametrize_index, test_name
29+
)
30+
31+
32+
def pytest_runtest_setup(item):
33+
if "incremental" in item.keywords:
34+
# retrieve the class name of the test
35+
cls_name = str(item.cls)
36+
# check if a previous test has failed for this class
37+
if cls_name in _test_failed_incremental:
38+
# retrieve the index of the test (if parametrize is used
39+
# in combination with incremental)
40+
parametrize_index = (
41+
tuple(item.callspec.indices.values())
42+
if hasattr(item, "callspec")
43+
else ()
44+
)
45+
# retrieve the name of the first test function to
46+
# fail for this class name and index
47+
test_name = _test_failed_incremental[cls_name].get(parametrize_index, None)
48+
# if name found, test has failed for the combination of
49+
# class name & test name
50+
if test_name is not None:
51+
pytest.xfail(f"previous test failed ({test_name})")

src/functions/pyproject.toml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
[project]
2+
name = "supabase_functions"
3+
version = "0.10.1" # {x-release-please-version}
4+
description = "Library for Supabase Functions"
5+
authors = [
6+
{ name = "Joel Lee", email = "[email protected]" },
7+
{ name = "Andrew Smith", email = "[email protected]" },
8+
]
9+
license = "MIT"
10+
readme = "README.md"
11+
repository = "https://github.com/supabase/supabase-py"
12+
requires-python = ">=3.9"
13+
dependencies = [
14+
"httpx[http2] >=0.26,<0.29",
15+
"strenum >=0.4.15",
16+
]
17+
18+
[dependency-groups]
19+
tests = [
20+
"pyjwt >=2.8.0",
21+
"pytest >=7.4.2,<9.0.0",
22+
"pytest-cov >=4,<7",
23+
"pytest-asyncio >=0.21.1,<1.2.0",
24+
]
25+
lints = [
26+
"unasync>=0.6.0",
27+
"ruff >=0.12.1",
28+
"pre-commit >=3.4,<5.0"
29+
]
30+
dev = [{ include-group = "lints" }, {include-group = "tests" }]
31+
32+
[tool.uv]
33+
default-groups = [ "dev" ]
34+
35+
[tool.pytest.ini_options]
36+
asyncio_mode = "auto"
37+
addopts = "tests"
38+
filterwarnings = [
39+
"ignore::DeprecationWarning", # ignore deprecation warnings globally
40+
]
41+
42+
[build-system]
43+
requires = ["uv_build>=0.8.3,<0.9.0"]
44+
build-backend = "uv_build"

src/functions/run-unasync.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import unasync
2+
from pathlib import Path
3+
4+
paths = Path("src/functions").glob("**/*.py")
5+
tests = Path("tests").glob("**/*.py")
6+
7+
rules = (unasync._DEFAULT_RULE,)
8+
9+
files = [str(p) for p in list(paths) + list(tests)]
10+
11+
if __name__ == "__main__":
12+
unasync.unasync_files(files, rules=rules)

0 commit comments

Comments
 (0)