From 61d8778a1488c9a21808848e30a353d02c1ba464 Mon Sep 17 00:00:00 2001 From: Hsin Cheng Date: Tue, 14 Apr 2026 18:44:07 +0200 Subject: [PATCH 1/5] Fix: use glob pattern in vercel.json functions key Vercel CLI 51+ requires a glob pattern in the `functions` key, not an exact file path. "api/index.py" was rejected with "doesn't match any Serverless Functions"; "api/**/*.py" is the documented correct form. Co-Authored-By: Claude Opus 4.6 --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index 33e6a33..c7a73f3 100644 --- a/vercel.json +++ b/vercel.json @@ -4,7 +4,7 @@ { "source": "/(.*)", "destination": "/api/index" } ], "functions": { - "api/index.py": { + "api/**/*.py": { "excludeFiles": "{tests/**,**/*.test.py,**/test_*.py}" } } From 96c749b5890ac4af14f42c75d46961ae85370d27 Mon Sep 17 00:00:00 2001 From: Hsin Cheng Date: Tue, 14 Apr 2026 18:50:47 +0200 Subject: [PATCH 2/5] Fix: remove functions key from vercel.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both exact-path and glob patterns in the `functions` key fail with "doesn't match any Serverless Functions" — meaning Vercel's auto- detection isn't finding the Python function before the validation runs. Dropping the `functions` key entirely lets Vercel auto-detect api/index.py as a Python serverless function without the validation step blocking the build. The excludeFiles optimisation can be re-added once the base deployment is confirmed working. Co-Authored-By: Claude Opus 4.6 --- vercel.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/vercel.json b/vercel.json index c7a73f3..f308795 100644 --- a/vercel.json +++ b/vercel.json @@ -2,10 +2,5 @@ "$schema": "https://openapi.vercel.sh/vercel.json", "rewrites": [ { "source": "/(.*)", "destination": "/api/index" } - ], - "functions": { - "api/**/*.py": { - "excludeFiles": "{tests/**,**/*.test.py,**/test_*.py}" - } - } + ] } From 7223ec1c24250f5fa5ee0b2b1a7c6823c0a5641c Mon Sep 17 00:00:00 2001 From: Hsin Cheng Date: Tue, 14 Apr 2026 19:09:10 +0200 Subject: [PATCH 3/5] =?UTF-8?q?Fix:=20rename=20app/main.py=20=E2=86=92=20a?= =?UTF-8?q?pp/application.py=20to=20avoid=20Vercel=20detection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Vercel scans the `app/` directory for recognised Python entrypoint filenames (main.py, app.py, server.py, index.py, wsgi.py, asgi.py) and treats any match as a serverless function. `app/main.py` was being detected and imported directly — without the project dependencies installed — causing FUNCTION_INVOCATION_FAILED on every request. Renaming to `application.py` (not in Vercel's detection list) makes `api/index.py` the sole entry point as intended. Updated: api/index.py, tests/conftest.py, CLAUDE.md, README.md. Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 2 +- README.md | 2 +- api/index.py | 2 +- app/{main.py => application.py} | 0 tests/conftest.py | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename app/{main.py => application.py} (100%) diff --git a/CLAUDE.md b/CLAUDE.md index 78f0316..521c75e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,7 +13,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co pip install -e ".[dev]" # Run dev server -uvicorn app.main:app --reload +uvicorn app.application:app --reload # Run all tests pytest diff --git a/README.md b/README.md index a1e9fd1..83cce78 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Python/FastAPI backend for duty scheduling at [US Basketball Amsterdam](https:// pip install -e ".[dev]" cp .env.example .env # set DATABASE_URL, ADMIN_PASSWORD, JWT_SECRET alembic upgrade head -uvicorn app.main:app --reload +uvicorn app.application:app --reload ``` API docs available at `http://localhost:8000/docs`. diff --git a/api/index.py b/api/index.py index dae8f9c..c05246a 100644 --- a/api/index.py +++ b/api/index.py @@ -1 +1 @@ -from app.main import app # noqa: F401 — Vercel looks for `app` at module level +from app.application import app # noqa: F401 — Vercel looks for `app` at module level diff --git a/app/main.py b/app/application.py similarity index 100% rename from app/main.py rename to app/application.py diff --git a/tests/conftest.py b/tests/conftest.py index 65b766e..1cf1ac7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,7 +10,7 @@ from app.db.engine import Base from app.dependencies import get_db -from app.main import app +from app.application import app TEST_DATABASE_URL = "sqlite:///:memory:" From 59c72e8b89621a820d878f514acd98449a83037f Mon Sep 17 00:00:00 2001 From: Hsin Cheng Date: Tue, 14 Apr 2026 19:27:33 +0200 Subject: [PATCH 4/5] Fix: move httpx to main dependencies in pyproject.toml httpx was only in [dev] extras, so Vercel (which runs pip install . not pip install .[dev]) did not install it. httpx is used in production code (app/services/foys.py) so it belongs in the main dependency list. Co-Authored-By: Claude Opus 4.6 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 906514b..ed63d55 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,12 +13,12 @@ dependencies = [ "passlib[bcrypt]>=1.7", "pydantic-settings>=2.0", "python-dotenv>=1.0", + "httpx>=0.27", ] [project.optional-dependencies] dev = [ "pytest>=8.0", - "httpx>=0.27", "pytest-asyncio>=0.24", ] From fd606c54af63f786dbec3008b1547b4f9cf3dddb Mon Sep 17 00:00:00 2001 From: Hsin Cheng Date: Tue, 14 Apr 2026 19:28:19 +0200 Subject: [PATCH 5/5] =?UTF-8?q?Remove=20requirements.txt=20=E2=80=94=20sup?= =?UTF-8?q?erseded=20by=20pyproject.toml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All dependencies are now declared in pyproject.toml. Vercel reads pyproject.toml directly (pip install .), so requirements.txt was redundant and could cause confusion about which file is authoritative. Co-Authored-By: Claude Opus 4.6 --- requirements.txt | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index c889323..0000000 --- a/requirements.txt +++ /dev/null @@ -1,10 +0,0 @@ -fastapi>=0.115 -uvicorn[standard]>=0.32 -sqlalchemy>=2.0 -alembic>=1.14 -psycopg2-binary>=2.9 -python-jose[cryptography]>=3.3 -passlib[bcrypt]>=1.7 -pydantic-settings>=2.0 -python-dotenv>=1.0 -httpx>=0.27