@vercel/python 6.1.6 → 6.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +116 -128
  2. package/package.json +7 -2
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ var require_windows = __commonJS({
48
48
  "../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js"(exports, module2) {
49
49
  module2.exports = isexe;
50
50
  isexe.sync = sync;
51
- var fs5 = require("fs");
51
+ var fs4 = require("fs");
52
52
  function checkPathExt(path, options) {
53
53
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
54
54
  if (!pathext) {
@@ -73,12 +73,12 @@ var require_windows = __commonJS({
73
73
  return checkPathExt(path, options);
74
74
  }
75
75
  function isexe(path, options, cb) {
76
- fs5.stat(path, function(er, stat) {
76
+ fs4.stat(path, function(er, stat) {
77
77
  cb(er, er ? false : checkStat(stat, path, options));
78
78
  });
79
79
  }
80
80
  function sync(path, options) {
81
- return checkStat(fs5.statSync(path), path, options);
81
+ return checkStat(fs4.statSync(path), path, options);
82
82
  }
83
83
  }
84
84
  });
@@ -88,14 +88,14 @@ var require_mode = __commonJS({
88
88
  "../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js"(exports, module2) {
89
89
  module2.exports = isexe;
90
90
  isexe.sync = sync;
91
- var fs5 = require("fs");
91
+ var fs4 = require("fs");
92
92
  function isexe(path, options, cb) {
93
- fs5.stat(path, function(er, stat) {
93
+ fs4.stat(path, function(er, stat) {
94
94
  cb(er, er ? false : checkStat(stat, options));
95
95
  });
96
96
  }
97
97
  function sync(path, options) {
98
- return checkStat(fs5.statSync(path), options);
98
+ return checkStat(fs4.statSync(path), options);
99
99
  }
100
100
  function checkStat(stat, options) {
101
101
  return stat.isFile() && checkMode(stat, options);
@@ -119,7 +119,7 @@ var require_mode = __commonJS({
119
119
  // ../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
120
120
  var require_isexe = __commonJS({
121
121
  "../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports, module2) {
122
- var fs5 = require("fs");
122
+ var fs4 = require("fs");
123
123
  var core;
124
124
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
125
125
  core = require_windows();
@@ -395,7 +395,7 @@ var require_shebang_command = __commonJS({
395
395
  var require_readShebang = __commonJS({
396
396
  "../../node_modules/.pnpm/cross-spawn@6.0.5/node_modules/cross-spawn/lib/util/readShebang.js"(exports, module2) {
397
397
  "use strict";
398
- var fs5 = require("fs");
398
+ var fs4 = require("fs");
399
399
  var shebangCommand = require_shebang_command();
400
400
  function readShebang(command) {
401
401
  const size = 150;
@@ -408,9 +408,9 @@ var require_readShebang = __commonJS({
408
408
  }
409
409
  let fd;
410
410
  try {
411
- fd = fs5.openSync(command, "r");
412
- fs5.readSync(fd, buffer, 0, size, 0);
413
- fs5.closeSync(fd);
411
+ fd = fs4.openSync(command, "r");
412
+ fs4.readSync(fd, buffer, 0, size, 0);
413
+ fs4.closeSync(fd);
414
414
  } catch (e) {
415
415
  }
416
416
  return shebangCommand(buffer.toString());
@@ -1895,9 +1895,9 @@ var require_pump = __commonJS({
1895
1895
  "../../node_modules/.pnpm/pump@3.0.2/node_modules/pump/index.js"(exports, module2) {
1896
1896
  var once = require_once();
1897
1897
  var eos = require_end_of_stream();
1898
- var fs5;
1898
+ var fs4;
1899
1899
  try {
1900
- fs5 = require("fs");
1900
+ fs4 = require("fs");
1901
1901
  } catch (e) {
1902
1902
  }
1903
1903
  var noop = function() {
@@ -1909,9 +1909,9 @@ var require_pump = __commonJS({
1909
1909
  var isFS = function(stream) {
1910
1910
  if (!ancient)
1911
1911
  return false;
1912
- if (!fs5)
1912
+ if (!fs4)
1913
1913
  return false;
1914
- return (stream instanceof (fs5.ReadStream || noop) || stream instanceof (fs5.WriteStream || noop)) && isFn(stream.close);
1914
+ return (stream instanceof (fs4.ReadStream || noop) || stream instanceof (fs4.WriteStream || noop)) && isFn(stream.close);
1915
1915
  };
1916
1916
  var isRequest = function(stream) {
1917
1917
  return stream.setHeader && isFn(stream.abort);
@@ -2748,7 +2748,7 @@ __export(src_exports, {
2748
2748
  version: () => version
2749
2749
  });
2750
2750
  module.exports = __toCommonJS(src_exports);
2751
- var import_fs5 = __toESM(require("fs"));
2751
+ var import_fs4 = __toESM(require("fs"));
2752
2752
  var import_util = require("util");
2753
2753
  var import_path5 = require("path");
2754
2754
  var import_build_utils7 = require("@vercel/build-utils");
@@ -2767,6 +2767,7 @@ var import_path = require("path");
2767
2767
  var import_build_utils = require("@vercel/build-utils");
2768
2768
  var import_execa = __toESM(require_execa());
2769
2769
  var isWin = process.platform === "win32";
2770
+ var UV_PYTHON_DOWNLOADS_MODE = "automatic";
2770
2771
  var isInVirtualEnv = () => {
2771
2772
  return process.env.VIRTUAL_ENV;
2772
2773
  };
@@ -2790,8 +2791,17 @@ function useVirtualEnv(workPath, env, systemPython) {
2790
2791
  }
2791
2792
  return { pythonCmd };
2792
2793
  }
2794
+ function getProtectedUvEnv(baseEnv = process.env) {
2795
+ return {
2796
+ ...baseEnv,
2797
+ UV_PYTHON_DOWNLOADS: UV_PYTHON_DOWNLOADS_MODE
2798
+ };
2799
+ }
2793
2800
  function createVenvEnv(venvPath, baseEnv = process.env) {
2794
- const env = { ...baseEnv, VIRTUAL_ENV: venvPath };
2801
+ const env = {
2802
+ ...getProtectedUvEnv(baseEnv),
2803
+ VIRTUAL_ENV: venvPath
2804
+ };
2795
2805
  const binDir = getVenvBinDir(venvPath);
2796
2806
  const existingPath = env.PATH || process.env.PATH || "";
2797
2807
  env.PATH = existingPath ? `${binDir}${import_path.delimiter}${existingPath}` : binDir;
@@ -3079,7 +3089,7 @@ async function uvLock({
3079
3089
  const pretty = `${uvPath} ${args.join(" ")}`;
3080
3090
  (0, import_build_utils2.debug)(`Running "${pretty}" in ${projectDir}...`);
3081
3091
  try {
3082
- await (0, import_execa2.default)(uvPath, args, { cwd: projectDir });
3092
+ await (0, import_execa2.default)(uvPath, args, { cwd: projectDir, env: getProtectedUvEnv() });
3083
3093
  } catch (err) {
3084
3094
  throw new Error(
3085
3095
  `Failed to run "${pretty}": ${err instanceof Error ? err.message : String(err)}`
@@ -3318,7 +3328,8 @@ async function pipInstall(pipPath, uvPath, workPath, args, targetDir) {
3318
3328
  (0, import_build_utils2.debug)(`Running "${prettyUv}"...`);
3319
3329
  try {
3320
3330
  await (0, import_execa2.default)(uvPath, uvArgs, {
3321
- cwd: workPath
3331
+ cwd: workPath,
3332
+ env: getProtectedUvEnv()
3322
3333
  });
3323
3334
  return;
3324
3335
  } catch (err) {
@@ -3543,7 +3554,20 @@ var import_build_utils8 = require("@vercel/build-utils");
3543
3554
  // src/version.ts
3544
3555
  var import_build_utils3 = require("@vercel/build-utils");
3545
3556
  var import_which2 = __toESM(require_lib());
3557
+ var DEFAULT_PYTHON_VERSION = "3.12";
3546
3558
  var allOptions = [
3559
+ {
3560
+ version: "3.14",
3561
+ pipPath: "pip3.14",
3562
+ pythonPath: "python3.14",
3563
+ runtime: "python3.14"
3564
+ },
3565
+ {
3566
+ version: "3.13",
3567
+ pipPath: "pip3.13",
3568
+ pythonPath: "python3.13",
3569
+ runtime: "python3.13"
3570
+ },
3547
3571
  {
3548
3572
  version: "3.12",
3549
3573
  pipPath: "pip3.12",
@@ -3590,11 +3614,17 @@ function getLatestPythonVersion({
3590
3614
  if (isDev) {
3591
3615
  return getDevPythonVersion();
3592
3616
  }
3617
+ const defaultOption = allOptions.find(
3618
+ (opt) => opt.version === DEFAULT_PYTHON_VERSION
3619
+ );
3620
+ if (defaultOption && isInstalled2(defaultOption)) {
3621
+ return defaultOption;
3622
+ }
3593
3623
  const selection = allOptions.find(isInstalled2);
3594
3624
  if (!selection) {
3595
3625
  throw new import_build_utils3.NowBuildError({
3596
3626
  code: "PYTHON_NOT_FOUND",
3597
- link: "http://vercel.link/python-version",
3627
+ link: "https://vercel.link/python-version",
3598
3628
  message: `Unable to find any supported Python versions.`
3599
3629
  });
3600
3630
  }
@@ -3695,7 +3725,7 @@ function getSupportedPythonVersion({
3695
3725
  if (isDiscontinued(requested)) {
3696
3726
  throw new import_build_utils3.NowBuildError({
3697
3727
  code: "BUILD_UTILS_PYTHON_VERSION_DISCONTINUED",
3698
- link: "http://vercel.link/python-version",
3728
+ link: "https://vercel.link/python-version",
3699
3729
  message: `Python version "${requested.version}" detected in ${source} is discontinued and must be upgraded.`
3700
3730
  });
3701
3731
  }
@@ -3704,7 +3734,7 @@ function getSupportedPythonVersion({
3704
3734
  console.log(`Using Python ${selection.version} from ${source}`);
3705
3735
  } else {
3706
3736
  console.warn(
3707
- `Warning: Python version "${version2}" detected in ${source} is not installed and will be ignored. http://vercel.link/python-version`
3737
+ `Warning: Python version "${version2}" detected in ${source} is not installed and will be ignored. https://vercel.link/python-version`
3708
3738
  );
3709
3739
  console.log(
3710
3740
  `Falling back to latest installed version: ${selection.version}`
@@ -3712,7 +3742,7 @@ function getSupportedPythonVersion({
3712
3742
  }
3713
3743
  } else {
3714
3744
  console.warn(
3715
- `Warning: Python version "${version2}" detected in ${source} is invalid and will be ignored. http://vercel.link/python-version`
3745
+ `Warning: Python version "${version2}" detected in ${source} is invalid and will be ignored. https://vercel.link/python-version`
3716
3746
  );
3717
3747
  console.log(
3718
3748
  `Falling back to latest installed version: ${selection.version}`
@@ -3726,7 +3756,7 @@ function getSupportedPythonVersion({
3726
3756
  if (isDiscontinued(selection)) {
3727
3757
  throw new import_build_utils3.NowBuildError({
3728
3758
  code: "BUILD_UTILS_PYTHON_VERSION_DISCONTINUED",
3729
- link: "http://vercel.link/python-version",
3759
+ link: "https://vercel.link/python-version",
3730
3760
  message: `Python version "${selection.version}" declared in project configuration is discontinued and must be upgraded.`
3731
3761
  });
3732
3762
  }
@@ -3734,7 +3764,7 @@ function getSupportedPythonVersion({
3734
3764
  const d = selection.discontinueDate.toISOString().split("T")[0];
3735
3765
  const srcSuffix = declaredPythonVersion ? `detected in ${declaredPythonVersion.source}` : "selected by runtime";
3736
3766
  console.warn(
3737
- `Error: Python version "${selection.version}" ${srcSuffix} has reached End-of-Life. Deployments created on or after ${d} will fail to build. http://vercel.link/python-version`
3767
+ `Error: Python version "${selection.version}" ${srcSuffix} has reached End-of-Life. Deployments created on or after ${d} will fail to build. https://vercel.link/python-version`
3738
3768
  );
3739
3769
  }
3740
3770
  return selection;
@@ -3749,97 +3779,28 @@ function isInstalled2({ pipPath, pythonPath }) {
3749
3779
 
3750
3780
  // src/start-dev-server.ts
3751
3781
  var import_child_process = require("child_process");
3752
- var import_fs4 = require("fs");
3782
+ var import_fs3 = require("fs");
3753
3783
  var import_path4 = require("path");
3754
3784
  var import_build_utils6 = require("@vercel/build-utils");
3755
3785
 
3756
3786
  // src/entrypoint.ts
3757
- var import_fs3 = __toESM(require("fs"));
3758
3787
  var import_path3 = require("path");
3759
3788
  var import_build_utils4 = require("@vercel/build-utils");
3760
3789
  var import_build_utils5 = require("@vercel/build-utils");
3761
- var FASTAPI_ENTRYPOINT_FILENAMES = ["app", "index", "server", "main"];
3762
- var FASTAPI_ENTRYPOINT_DIRS = ["", "src", "app", "api"];
3763
- var FASTAPI_CONTENT_REGEX = /(from\s+fastapi\s+import\s+FastAPI|import\s+fastapi|FastAPI\s*\()/;
3764
- var FASTAPI_CANDIDATE_ENTRYPOINTS = FASTAPI_ENTRYPOINT_FILENAMES.flatMap(
3765
- (filename) => FASTAPI_ENTRYPOINT_DIRS.map(
3766
- (dir) => import_path3.posix.join(dir, `${filename}.py`)
3767
- )
3768
- );
3769
- function isFastapiEntrypoint(file) {
3770
- try {
3771
- const fsPath = file.fsPath;
3772
- if (!fsPath)
3773
- return false;
3774
- const contents = import_fs3.default.readFileSync(fsPath, "utf8");
3775
- return FASTAPI_CONTENT_REGEX.test(contents);
3776
- } catch {
3777
- return false;
3778
- }
3779
- }
3780
- var FLASK_ENTRYPOINT_FILENAMES = ["app", "index", "server", "main"];
3781
- var FLASK_ENTRYPOINT_DIRS = ["", "src", "app", "api"];
3782
- var FLASK_CONTENT_REGEX = /(from\s+flask\s+import\s+Flask|import\s+flask|Flask\s*\()/;
3783
- var FLASK_CANDIDATE_ENTRYPOINTS = FLASK_ENTRYPOINT_FILENAMES.flatMap(
3784
- (filename) => FLASK_ENTRYPOINT_DIRS.map(
3790
+ var PYTHON_ENTRYPOINT_FILENAMES = [
3791
+ "app",
3792
+ "index",
3793
+ "server",
3794
+ "main",
3795
+ "wsgi",
3796
+ "asgi"
3797
+ ];
3798
+ var PYTHON_ENTRYPOINT_DIRS = ["", "src", "app", "api"];
3799
+ var PYTHON_CANDIDATE_ENTRYPOINTS = PYTHON_ENTRYPOINT_FILENAMES.flatMap(
3800
+ (filename) => PYTHON_ENTRYPOINT_DIRS.map(
3785
3801
  (dir) => import_path3.posix.join(dir, `${filename}.py`)
3786
3802
  )
3787
3803
  );
3788
- function isFlaskEntrypoint(file) {
3789
- try {
3790
- const fsPath = file.fsPath;
3791
- if (!fsPath)
3792
- return false;
3793
- const contents = import_fs3.default.readFileSync(fsPath, "utf8");
3794
- return FLASK_CONTENT_REGEX.test(contents);
3795
- } catch {
3796
- return false;
3797
- }
3798
- }
3799
- async function detectFlaskEntrypoint(workPath, configuredEntrypoint) {
3800
- const entry = configuredEntrypoint.endsWith(".py") ? configuredEntrypoint : `${configuredEntrypoint}.py`;
3801
- try {
3802
- const fsFiles = await (0, import_build_utils4.glob)("**", workPath);
3803
- if (fsFiles[entry])
3804
- return entry;
3805
- const candidates = FLASK_CANDIDATE_ENTRYPOINTS.filter(
3806
- (c) => !!fsFiles[c]
3807
- );
3808
- if (candidates.length > 0) {
3809
- const flaskEntrypoint = candidates.find(
3810
- (c) => isFlaskEntrypoint(fsFiles[c])
3811
- ) || candidates[0];
3812
- (0, import_build_utils4.debug)(`Detected Flask entrypoint: ${flaskEntrypoint}`);
3813
- return flaskEntrypoint;
3814
- }
3815
- return null;
3816
- } catch {
3817
- (0, import_build_utils4.debug)("Failed to discover entrypoint for Flask");
3818
- return null;
3819
- }
3820
- }
3821
- async function detectFastapiEntrypoint(workPath, configuredEntrypoint) {
3822
- const entry = configuredEntrypoint.endsWith(".py") ? configuredEntrypoint : `${configuredEntrypoint}.py`;
3823
- try {
3824
- const fsFiles = await (0, import_build_utils4.glob)("**", workPath);
3825
- if (fsFiles[entry])
3826
- return entry;
3827
- const candidates = FASTAPI_CANDIDATE_ENTRYPOINTS.filter(
3828
- (c) => !!fsFiles[c]
3829
- );
3830
- if (candidates.length > 0) {
3831
- const fastapiEntrypoint = candidates.find(
3832
- (c) => isFastapiEntrypoint(fsFiles[c])
3833
- ) || candidates[0];
3834
- (0, import_build_utils4.debug)(`Detected FastAPI entrypoint: ${fastapiEntrypoint}`);
3835
- return fastapiEntrypoint;
3836
- }
3837
- return null;
3838
- } catch {
3839
- (0, import_build_utils4.debug)("Failed to discover entrypoint for FastAPI");
3840
- return null;
3841
- }
3842
- }
3843
3804
  async function getPyprojectEntrypoint(workPath) {
3844
3805
  const pyprojectData = await (0, import_build_utils5.readConfigFile)((0, import_path3.join)(workPath, "pyproject.toml"));
3845
3806
  if (!pyprojectData)
@@ -3866,13 +3827,38 @@ async function getPyprojectEntrypoint(workPath) {
3866
3827
  return null;
3867
3828
  }
3868
3829
  }
3869
- async function detectPythonEntrypoint(framework, workPath, configuredEntrypoint) {
3870
- let entrypoint = null;
3871
- if (framework === "fastapi") {
3872
- entrypoint = await detectFastapiEntrypoint(workPath, configuredEntrypoint);
3873
- } else if (framework === "flask") {
3874
- entrypoint = await detectFlaskEntrypoint(workPath, configuredEntrypoint);
3830
+ async function detectGenericPythonEntrypoint(workPath, configuredEntrypoint) {
3831
+ const entry = configuredEntrypoint.endsWith(".py") ? configuredEntrypoint : `${configuredEntrypoint}.py`;
3832
+ try {
3833
+ const fsFiles = await (0, import_build_utils4.glob)("**", workPath);
3834
+ if (fsFiles[entry]) {
3835
+ const isValid = await (0, import_build_utils4.isPythonEntrypoint)(fsFiles[entry]);
3836
+ if (isValid) {
3837
+ (0, import_build_utils4.debug)(`Using configured Python entrypoint: ${entry}`);
3838
+ return entry;
3839
+ }
3840
+ }
3841
+ const candidates = PYTHON_CANDIDATE_ENTRYPOINTS.filter(
3842
+ (c) => !!fsFiles[c]
3843
+ );
3844
+ for (const candidate of candidates) {
3845
+ const isValid = await (0, import_build_utils4.isPythonEntrypoint)(fsFiles[candidate]);
3846
+ if (isValid) {
3847
+ (0, import_build_utils4.debug)(`Detected Python entrypoint: ${candidate}`);
3848
+ return candidate;
3849
+ }
3850
+ }
3851
+ return null;
3852
+ } catch {
3853
+ (0, import_build_utils4.debug)("Failed to discover Python entrypoint");
3854
+ return null;
3875
3855
  }
3856
+ }
3857
+ async function detectPythonEntrypoint(_framework, workPath, configuredEntrypoint) {
3858
+ const entrypoint = await detectGenericPythonEntrypoint(
3859
+ workPath,
3860
+ configuredEntrypoint
3861
+ );
3876
3862
  if (entrypoint)
3877
3863
  return entrypoint;
3878
3864
  return await getPyprojectEntrypoint(workPath);
@@ -3954,12 +3940,12 @@ function installGlobalCleanupHandlers() {
3954
3940
  function createDevAsgiShim(workPath, modulePath) {
3955
3941
  try {
3956
3942
  const vercelPythonDir = (0, import_path4.join)(workPath, ".vercel", "python");
3957
- (0, import_fs4.mkdirSync)(vercelPythonDir, { recursive: true });
3943
+ (0, import_fs3.mkdirSync)(vercelPythonDir, { recursive: true });
3958
3944
  const shimPath = (0, import_path4.join)(vercelPythonDir, `${ASGI_SHIM_MODULE}.py`);
3959
3945
  const templatePath = (0, import_path4.join)(__dirname, "..", `${ASGI_SHIM_MODULE}.py`);
3960
- const template = (0, import_fs4.readFileSync)(templatePath, "utf8");
3946
+ const template = (0, import_fs3.readFileSync)(templatePath, "utf8");
3961
3947
  const shimSource = template.replace(/__VC_DEV_MODULE_PATH__/g, modulePath);
3962
- (0, import_fs4.writeFileSync)(shimPath, shimSource, "utf8");
3948
+ (0, import_fs3.writeFileSync)(shimPath, shimSource, "utf8");
3963
3949
  (0, import_build_utils6.debug)(`Prepared Python dev static shim at ${shimPath}`);
3964
3950
  return ASGI_SHIM_MODULE;
3965
3951
  } catch (err) {
@@ -3970,12 +3956,12 @@ function createDevAsgiShim(workPath, modulePath) {
3970
3956
  function createDevWsgiShim(workPath, modulePath) {
3971
3957
  try {
3972
3958
  const vercelPythonDir = (0, import_path4.join)(workPath, ".vercel", "python");
3973
- (0, import_fs4.mkdirSync)(vercelPythonDir, { recursive: true });
3959
+ (0, import_fs3.mkdirSync)(vercelPythonDir, { recursive: true });
3974
3960
  const shimPath = (0, import_path4.join)(vercelPythonDir, `${WSGI_SHIM_MODULE}.py`);
3975
3961
  const templatePath = (0, import_path4.join)(__dirname, "..", `${WSGI_SHIM_MODULE}.py`);
3976
- const template = (0, import_fs4.readFileSync)(templatePath, "utf8");
3962
+ const template = (0, import_fs3.readFileSync)(templatePath, "utf8");
3977
3963
  const shimSource = template.replace(/__VC_DEV_MODULE_PATH__/g, modulePath);
3978
- (0, import_fs4.writeFileSync)(shimPath, shimSource, "utf8");
3964
+ (0, import_fs3.writeFileSync)(shimPath, shimSource, "utf8");
3979
3965
  (0, import_build_utils6.debug)(`Prepared Python dev WSGI shim at ${shimPath}`);
3980
3966
  return WSGI_SHIM_MODULE;
3981
3967
  } catch (err) {
@@ -3998,7 +3984,7 @@ var startDevServer = async (opts) => {
3998
3984
  rawEntrypoint
3999
3985
  );
4000
3986
  if (!entry) {
4001
- const searched = framework === "fastapi" ? FASTAPI_CANDIDATE_ENTRYPOINTS.join(", ") : FLASK_CANDIDATE_ENTRYPOINTS.join(", ");
3987
+ const searched = PYTHON_CANDIDATE_ENTRYPOINTS.join(", ");
4002
3988
  throw new import_build_utils6.NowBuildError({
4003
3989
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
4004
3990
  message: `No ${framework} entrypoint found. Add an 'app' script in pyproject.toml or define an entrypoint in one of: ${searched}.`,
@@ -4074,7 +4060,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
4074
4060
  }
4075
4061
  }
4076
4062
  }
4077
- if (framework === "fastapi") {
4063
+ if (framework !== "flask") {
4078
4064
  const devShimModule = createDevAsgiShim(workPath, modulePath);
4079
4065
  if (devShimModule) {
4080
4066
  const vercelPythonDir = (0, import_path4.join)(workPath, ".vercel", "python");
@@ -4083,7 +4069,9 @@ If you are using a virtual environment, activate it before running "vercel dev",
4083
4069
  }
4084
4070
  const moduleToRun = devShimModule || modulePath;
4085
4071
  const argv = ["-u", "-m", moduleToRun];
4086
- (0, import_build_utils6.debug)(`Starting ASGI dev server: ${pythonCmd} ${argv.join(" ")}`);
4072
+ (0, import_build_utils6.debug)(
4073
+ `Starting ASGI dev server (${framework}): ${pythonCmd} ${argv.join(" ")}`
4074
+ );
4087
4075
  const child = (0, import_child_process.spawn)(pythonCmd, argv, {
4088
4076
  cwd: workPath,
4089
4077
  env,
@@ -4248,8 +4236,8 @@ If you are using a virtual environment, activate it before running "vercel dev",
4248
4236
  };
4249
4237
 
4250
4238
  // src/index.ts
4251
- var readFile = (0, import_util.promisify)(import_fs5.default.readFile);
4252
- var writeFile = (0, import_util.promisify)(import_fs5.default.writeFile);
4239
+ var readFile = (0, import_util.promisify)(import_fs4.default.readFile);
4240
+ var writeFile = (0, import_util.promisify)(import_fs4.default.writeFile);
4253
4241
  var version = 3;
4254
4242
  async function downloadFilesInWorkPath({
4255
4243
  entrypoint,
@@ -4294,7 +4282,7 @@ var build = async ({
4294
4282
  console.log('Failed to create "setup.cfg" file');
4295
4283
  throw err;
4296
4284
  }
4297
- if (framework === "fastapi" || framework === "flask") {
4285
+ if ((0, import_build_utils7.isPythonFramework)(framework)) {
4298
4286
  const {
4299
4287
  cliType,
4300
4288
  lockfileVersion,
@@ -4335,7 +4323,7 @@ var build = async ({
4335
4323
  }
4336
4324
  }
4337
4325
  let fsFiles = await (0, import_build_utils7.glob)("**", workPath);
4338
- if ((framework === "fastapi" || framework === "flask") && (!fsFiles[entrypoint] || !entrypoint.endsWith(".py"))) {
4326
+ if ((0, import_build_utils7.isPythonFramework)(framework) && (!fsFiles[entrypoint] || !entrypoint.endsWith(".py"))) {
4339
4327
  const detected = await detectPythonEntrypoint(
4340
4328
  config.framework,
4341
4329
  workPath,
@@ -4347,7 +4335,7 @@ var build = async ({
4347
4335
  );
4348
4336
  entrypoint = detected;
4349
4337
  } else {
4350
- const searchedList = framework === "fastapi" ? FASTAPI_CANDIDATE_ENTRYPOINTS.join(", ") : FLASK_CANDIDATE_ENTRYPOINTS.join(", ");
4338
+ const searchedList = PYTHON_CANDIDATE_ENTRYPOINTS.join(", ");
4351
4339
  throw new import_build_utils7.NowBuildError({
4352
4340
  code: `${framework.toUpperCase()}_ENTRYPOINT_NOT_FOUND`,
4353
4341
  message: `No ${framework} entrypoint found. Add an 'app' script in pyproject.toml or define an entrypoint in one of: ${searchedList}.`,
@@ -4412,7 +4400,7 @@ var build = async ({
4412
4400
  pythonPath: pythonVersion.pythonPath,
4413
4401
  venvPath
4414
4402
  });
4415
- const hasCustomInstallCommand = (framework === "fastapi" || framework === "flask") && !!projectInstallCommand;
4403
+ const hasCustomInstallCommand = (0, import_build_utils7.isPythonFramework)(framework) && !!projectInstallCommand;
4416
4404
  if (hasCustomInstallCommand) {
4417
4405
  const baseEnv = spawnEnv || process.env;
4418
4406
  const pythonEnv = createVenvEnv(venvPath, baseEnv);
@@ -4425,7 +4413,7 @@ var build = async ({
4425
4413
  });
4426
4414
  } else {
4427
4415
  let ranPyprojectInstall = false;
4428
- if (framework === "fastapi" || framework === "flask") {
4416
+ if ((0, import_build_utils7.isPythonFramework)(framework)) {
4429
4417
  const baseEnv = spawnEnv || process.env;
4430
4418
  const pythonEnv = createVenvEnv(venvPath, baseEnv);
4431
4419
  pythonEnv.VERCEL_PYTHON_VENV_PATH = venvPath;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/python",
3
- "version": "6.1.6",
3
+ "version": "6.2.1",
4
4
  "main": "./dist/index.js",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
@@ -16,6 +16,7 @@
16
16
  "directory": "packages/python"
17
17
  },
18
18
  "devDependencies": {
19
+ "@renovatebot/pep440": "4.2.1",
19
20
  "@types/execa": "^0.9.0",
20
21
  "@types/fs-extra": "11.0.2",
21
22
  "@types/jest": "27.4.1",
@@ -25,8 +26,12 @@
25
26
  "execa": "^1.0.0",
26
27
  "fs-extra": "11.1.1",
27
28
  "jest-junit": "16.0.0",
29
+ "minimatch": "10.1.1",
30
+ "pip-requirements-js": "1.0.2",
31
+ "smol-toml": "1.5.2",
28
32
  "which": "3.0.0",
29
- "@vercel/build-utils": "13.2.4"
33
+ "@vercel/build-utils": "13.2.13",
34
+ "@vercel/error-utils": "2.0.3"
30
35
  },
31
36
  "scripts": {
32
37
  "build": "node ../../utils/build-builder.mjs",