-
Notifications
You must be signed in to change notification settings - Fork 3.2k
[python] support arbitrary python frameworks with pyproject.toml
#14380
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: b51a906 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Add changeset for supporting arbitrary Python frameworks.
🧪 Test StrategyComparing: Strategy: Affected packages only ✅ Only testing packages that have been modified or depend on modified packages. This saves time while maintaining safety. Affected packages (6):
E2E Tests: Only affected package e2e tests will run This comment is automatically generated based on the affected testing strategy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional Suggestion:
The 'pyproject' framework is not supported by the dev server, preventing users from running vercel dev with the new generic Python framework. The framework check explicitly excludes 'pyproject', causing the function to return null and opt-out of dev server support.
View Details
📝 Patch Details
diff --git a/packages/python/src/start-dev-server.ts b/packages/python/src/start-dev-server.ts
index 026ce7b7e..79049b17f 100644
--- a/packages/python/src/start-dev-server.ts
+++ b/packages/python/src/start-dev-server.ts
@@ -162,9 +162,9 @@ function createDevWsgiShim(
export const startDevServer: StartDevServer = async opts => {
const { entrypoint: rawEntrypoint, workPath, meta = {}, config } = opts;
- // Only start a dev server for FastAPI or Flask for now
+ // Only start a dev server for FastAPI, Flask, or generic pyproject for now
const framework = config?.framework;
- if (framework !== 'fastapi' && framework !== 'flask') {
+ if (framework !== 'fastapi' && framework !== 'flask' && framework !== 'pyproject') {
return null;
}
@@ -177,15 +177,19 @@ export const startDevServer: StartDevServer = async opts => {
rawEntrypoint
);
if (!entry) {
- const searched =
- framework === 'fastapi'
- ? FASTAPI_CANDIDATE_ENTRYPOINTS.join(', ')
- : FLASK_CANDIDATE_ENTRYPOINTS.join(', ');
+ let searched: string;
+ if (framework === 'fastapi') {
+ searched = FASTAPI_CANDIDATE_ENTRYPOINTS.join(', ');
+ } else if (framework === 'flask') {
+ searched = FLASK_CANDIDATE_ENTRYPOINTS.join(', ');
+ } else {
+ searched = 'Define an \'app\' script in pyproject.toml';
+ }
throw new NowBuildError({
code: 'PYTHON_ENTRYPOINT_NOT_FOUND',
message: `No ${framework} entrypoint found. Add an 'app' script in pyproject.toml or define an entrypoint in one of: ${searched}.`,
- link: `https://vercel.com/docs/frameworks/backend/${framework?.toLowerCase()}#exporting-the-${framework?.toLowerCase()}-application`,
- action: 'Learn More',
+ link: framework !== 'pyproject' ? `https://vercel.com/docs/frameworks/backend/${framework?.toLowerCase()}#exporting-the-${framework?.toLowerCase()}-application` : undefined,
+ action: framework !== 'pyproject' ? 'Learn More' : undefined,
});
}
@@ -276,7 +280,7 @@ export const startDevServer: StartDevServer = async opts => {
}
}
- if (framework === 'fastapi') {
+ if (framework === 'fastapi' || framework === 'pyproject') {
// Create a tiny ASGI shim that serves static files first (when present)
// and falls back to the user's app. Always applied for consistent behavior.
const devShimModule = createDevAsgiShim(workPath, modulePath);
Analysis
The 'pyproject' framework is not supported by the dev server, preventing vercel dev with generic Python frameworks
What fails: The startDevServer() function in packages/python/src/start-dev-server.ts explicitly excludes the 'pyproject' framework via a framework type check on line 167, causing it to return null and opt-out of dev server support.
How to reproduce:
- Create a Python project with a generic ASGI/WSGI framework (e.g., Starlette) configured via
pyproject.tomlwith a[project.scripts]section defining anappentrypoint - Run
vercel devwithframework: 'pyproject'in the Vercel configuration - The dev server fails to start because
startDevServer()returnsnull
Result: Users with framework: 'pyproject' configuration cannot use vercel dev for local development, even though production deployments work correctly.
Expected: The dev server should support the 'pyproject' framework the same way it supports 'fastapi' and 'flask'. Since the test fixture 45-pyproject-app uses Starlette (an ASGI framework), it should route through the ASGI code path.
Fix implemented:
- Updated line 167 to include
'pyproject'in the framework check - Updated line 305 to route
'pyproject'to the ASGI code path (matching the behavior for FastAPI) - Updated error handling for entrypoint detection to handle
'pyproject'framework appropriately
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional Suggestion:
The pyproject framework doesn't execute custom install and build commands configured in vercel.json or the Vercel dashboard, even though the framework definition allows them to be configured. This will cause deployments to fail if users rely on custom install commands like uv sync.
View Details
📝 Patch Details
diff --git a/packages/python/src/index.ts b/packages/python/src/index.ts
index bc0d62167..969bcac73 100644
--- a/packages/python/src/index.ts
+++ b/packages/python/src/index.ts
@@ -118,8 +118,8 @@ export const build: BuildV3 = async ({
throw err;
}
- // For FastAPI/Flask, also honor project install/build commands (vercel.json/dashboard)
- if (framework === 'fastapi' || framework === 'flask') {
+ // For FastAPI/Flask/Pyproject, also honor project install/build commands (vercel.json/dashboard)
+ if (framework === 'fastapi' || framework === 'flask' || framework === 'pyproject') {
const {
cliType,
lockfileVersion,
Analysis
Custom install and build commands not executed for pyproject framework
What fails: The pyproject framework doesn't execute custom install and build commands configured in vercel.json or the Vercel dashboard, even though the framework definition explicitly supports these settings with installCommand placeholder of `uv sync`.
How to reproduce:
- Create a Python project with
pyproject.tomlthat uses[project.scripts]with anappentry - Configure a custom install command (e.g.,
uv sync) invercel.jsonor Vercel dashboard for thepyprojectframework - Deploy the project to Vercel
Result: The custom install command is silently ignored. The build output shows no record of the uv sync command running.
Expected: The custom install command should run before attempting to install dependencies, as it does for fastapi and flask frameworks (per the code logic at packages/python/src/index.ts line 122).
Root cause: Line 122 in packages/python/src/index.ts only checks for framework === 'fastapi' || framework === 'flask', excluding framework === 'pyproject'. This prevents the projectSettings.installCommand and projectSettings.buildCommand blocks from executing for pyproject deployments, even though the framework definition in packages/frameworks/src/frameworks.ts (line 3865) declares these settings as configurable with installCommand: { placeholder: 'uv sync' }.
Impact: Users cannot use alternative installation methods like uv sync or poetry install for pyproject deployments. They are limited to the automatic uv export + install flow, which differs from direct uv/poetry package manager workflows. This is a breaking limitation for projects that require specific dependency resolution or installation approaches.
Support zero-config deployments for arbitrary Python frameworks so long as they contain an app script in
project.scriptsinpyproject.toml, e.g:vc devsuport in: #14383