@vercel/python 6.1.2 → 6.1.4

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 +131 -80
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -137,12 +137,12 @@ var require_isexe = __commonJS({
137
137
  if (typeof Promise !== "function") {
138
138
  throw new TypeError("callback not provided");
139
139
  }
140
- return new Promise(function(resolve, reject) {
140
+ return new Promise(function(resolve2, reject) {
141
141
  isexe(path, options || {}, function(er, is) {
142
142
  if (er) {
143
143
  reject(er);
144
144
  } else {
145
- resolve(is);
145
+ resolve2(is);
146
146
  }
147
147
  });
148
148
  });
@@ -2042,7 +2042,7 @@ var require_get_stream = __commonJS({
2042
2042
  options = Object.assign({ maxBuffer: Infinity }, options);
2043
2043
  const { maxBuffer } = options;
2044
2044
  let stream;
2045
- return new Promise((resolve, reject) => {
2045
+ return new Promise((resolve2, reject) => {
2046
2046
  const rejectPromise = (error) => {
2047
2047
  if (error) {
2048
2048
  error.bufferedData = stream.getBufferedValue();
@@ -2054,7 +2054,7 @@ var require_get_stream = __commonJS({
2054
2054
  rejectPromise(error);
2055
2055
  return;
2056
2056
  }
2057
- resolve();
2057
+ resolve2();
2058
2058
  });
2059
2059
  stream.on("data", () => {
2060
2060
  if (stream.getBufferedLength() > maxBuffer) {
@@ -2078,11 +2078,11 @@ var require_p_finally = __commonJS({
2078
2078
  onFinally = onFinally || (() => {
2079
2079
  });
2080
2080
  return promise.then(
2081
- (val) => new Promise((resolve) => {
2082
- resolve(onFinally());
2081
+ (val) => new Promise((resolve2) => {
2082
+ resolve2(onFinally());
2083
2083
  }).then(() => val),
2084
- (err) => new Promise((resolve) => {
2085
- resolve(onFinally());
2084
+ (err) => new Promise((resolve2) => {
2085
+ resolve2(onFinally());
2086
2086
  }).then(() => {
2087
2087
  throw err;
2088
2088
  })
@@ -2461,8 +2461,8 @@ var require_execa = __commonJS({
2461
2461
  }
2462
2462
  let ret;
2463
2463
  if (!buffer) {
2464
- ret = new Promise((resolve, reject) => {
2465
- process2[stream].once("end", resolve).once("error", reject);
2464
+ ret = new Promise((resolve2, reject) => {
2465
+ process2[stream].once("end", resolve2).once("error", reject);
2466
2466
  });
2467
2467
  } else if (encoding) {
2468
2468
  ret = _getStream(process2[stream], {
@@ -2551,19 +2551,19 @@ ${stderr}${stdout}`;
2551
2551
  spawned.kill(parsed.opts.killSignal);
2552
2552
  }, parsed.opts.timeout);
2553
2553
  }
2554
- const processDone = new Promise((resolve) => {
2554
+ const processDone = new Promise((resolve2) => {
2555
2555
  spawned.on("exit", (code, signal) => {
2556
2556
  cleanup();
2557
- resolve({ code, signal });
2557
+ resolve2({ code, signal });
2558
2558
  });
2559
2559
  spawned.on("error", (err) => {
2560
2560
  cleanup();
2561
- resolve({ error: err });
2561
+ resolve2({ error: err });
2562
2562
  });
2563
2563
  if (spawned.stdin) {
2564
2564
  spawned.stdin.on("error", (err) => {
2565
2565
  cleanup();
2566
- resolve({ error: err });
2566
+ resolve2({ error: err });
2567
2567
  });
2568
2568
  }
2569
2569
  });
@@ -2754,7 +2754,7 @@ var import_path5 = require("path");
2754
2754
  var import_build_utils7 = require("@vercel/build-utils");
2755
2755
 
2756
2756
  // src/install.ts
2757
- var import_execa = __toESM(require_execa());
2757
+ var import_execa2 = __toESM(require_execa());
2758
2758
  var import_fs2 = __toESM(require("fs"));
2759
2759
  var import_os = __toESM(require("os"));
2760
2760
  var import_path2 = require("path");
@@ -2765,7 +2765,7 @@ var import_build_utils2 = require("@vercel/build-utils");
2765
2765
  var import_fs = __toESM(require("fs"));
2766
2766
  var import_path = require("path");
2767
2767
  var import_build_utils = require("@vercel/build-utils");
2768
- var execa = require_execa();
2768
+ var import_execa = __toESM(require_execa());
2769
2769
  var isWin = process.platform === "win32";
2770
2770
  var isInVirtualEnv = () => {
2771
2771
  return process.env.VIRTUAL_ENV;
@@ -2809,12 +2809,12 @@ async function ensureVenv({
2809
2809
  }
2810
2810
  await import_fs.default.promises.mkdir(venvPath, { recursive: true });
2811
2811
  console.log(`Creating virtual environment at "${venvPath}"...`);
2812
- await execa(pythonPath, ["-m", "venv", venvPath]);
2812
+ await (0, import_execa.default)(pythonPath, ["-m", "venv", venvPath]);
2813
2813
  }
2814
2814
  function getVenvPythonBin(venvPath) {
2815
2815
  return (0, import_path.join)(getVenvBinDir(venvPath), isWin ? "python.exe" : "python");
2816
2816
  }
2817
- async function runPyprojectScript(workPath, scriptNames, env) {
2817
+ async function runPyprojectScript(workPath, scriptNames, env, useUserVirtualEnv = true) {
2818
2818
  const pyprojectPath = (0, import_path.join)(workPath, "pyproject.toml");
2819
2819
  if (!import_fs.default.existsSync(pyprojectPath))
2820
2820
  return false;
@@ -2832,7 +2832,9 @@ async function runPyprojectScript(workPath, scriptNames, env) {
2832
2832
  return false;
2833
2833
  const systemPython = process.platform === "win32" ? "python" : "python3";
2834
2834
  const finalEnv = { ...process.env, ...env };
2835
- useVirtualEnv(workPath, finalEnv, systemPython);
2835
+ if (useUserVirtualEnv) {
2836
+ useVirtualEnv(workPath, finalEnv, systemPython);
2837
+ }
2836
2838
  const scriptCommand = scripts[scriptToRun];
2837
2839
  if (typeof scriptCommand === "string" && scriptCommand.trim()) {
2838
2840
  console.log(`Executing: ${scriptCommand}`);
@@ -2852,15 +2854,23 @@ async function runUvCommand(options) {
2852
2854
  throw new Error(`uv is required to run "${pretty}" but is not available`);
2853
2855
  }
2854
2856
  try {
2855
- await execa(uvPath, args, {
2857
+ await (0, import_execa.default)(uvPath, args, {
2856
2858
  cwd,
2857
2859
  env: createVenvEnv(venvPath)
2858
2860
  });
2859
2861
  return true;
2860
2862
  } catch (err) {
2861
- throw new Error(
2863
+ const error = new Error(
2862
2864
  `Failed to run "${pretty}": ${err instanceof Error ? err.message : String(err)}`
2863
2865
  );
2866
+ if (err && typeof err === "object") {
2867
+ if ("code" in err) {
2868
+ error.code = err.code;
2869
+ } else if ("signal" in err) {
2870
+ error.code = err.signal;
2871
+ }
2872
+ }
2873
+ throw error;
2864
2874
  }
2865
2875
  }
2866
2876
  function findDir({
@@ -2889,7 +2899,7 @@ print(spec.origin)
2889
2899
  `;
2890
2900
  async function isInstalled(pythonPath, dependency, cwd) {
2891
2901
  try {
2892
- const { stdout } = await (0, import_execa.default)(
2902
+ const { stdout } = await (0, import_execa2.default)(
2893
2903
  pythonPath,
2894
2904
  ["-c", makeDependencyCheckCode(dependency)],
2895
2905
  {
@@ -2912,7 +2922,7 @@ pkg_resources.require(dependencies)
2912
2922
  `;
2913
2923
  async function areRequirementsInstalled(pythonPath, requirementsPath, cwd) {
2914
2924
  try {
2915
- await (0, import_execa.default)(
2925
+ await (0, import_execa2.default)(
2916
2926
  pythonPath,
2917
2927
  ["-c", makeRequirementsCheckCode(requirementsPath)],
2918
2928
  {
@@ -2932,7 +2942,7 @@ async function runUvSync({
2932
2942
  projectDir,
2933
2943
  locked
2934
2944
  }) {
2935
- const args = ["sync", "--active", "--no-dev"];
2945
+ const args = ["sync", "--active", "--no-dev", "--link-mode", "copy"];
2936
2946
  if (locked) {
2937
2947
  args.push("--locked");
2938
2948
  }
@@ -2955,7 +2965,7 @@ for key in ("purelib", "platlib"):
2955
2965
  paths.append(candidate)
2956
2966
  print(json.dumps(paths))
2957
2967
  `.trim();
2958
- const { stdout } = await (0, import_execa.default)(pythonBin, ["-c", code]);
2968
+ const { stdout } = await (0, import_execa2.default)(pythonBin, ["-c", code]);
2959
2969
  try {
2960
2970
  const parsed = JSON.parse(stdout);
2961
2971
  if (Array.isArray(parsed)) {
@@ -3069,7 +3079,7 @@ async function uvLock({
3069
3079
  const pretty = `${uvPath} ${args.join(" ")}`;
3070
3080
  (0, import_build_utils2.debug)(`Running "${pretty}" in ${projectDir}...`);
3071
3081
  try {
3072
- await (0, import_execa.default)(uvPath, args, { cwd: projectDir });
3082
+ await (0, import_execa2.default)(uvPath, args, { cwd: projectDir });
3073
3083
  } catch (err) {
3074
3084
  throw new Error(
3075
3085
  `Failed to run "${pretty}": ${err instanceof Error ? err.message : String(err)}`
@@ -3122,10 +3132,23 @@ async function filterMissingRuntimeDependencies({
3122
3132
  return !declaredNames.has(name);
3123
3133
  });
3124
3134
  }
3135
+ function findUvLockUpwards(startDir, repoRootPath) {
3136
+ const start = (0, import_path2.resolve)(startDir);
3137
+ const base = repoRootPath ? (0, import_path2.resolve)(repoRootPath) : void 0;
3138
+ for (const dir of (0, import_build_utils2.traverseUpDirectories)({ start, base })) {
3139
+ const lockPath = (0, import_path2.join)(dir, "uv.lock");
3140
+ const pyprojectPath = (0, import_path2.join)(dir, "pyproject.toml");
3141
+ if (import_fs2.default.existsSync(lockPath) && import_fs2.default.existsSync(pyprojectPath)) {
3142
+ return lockPath;
3143
+ }
3144
+ }
3145
+ return null;
3146
+ }
3125
3147
  async function ensureUvProject({
3126
3148
  workPath,
3127
3149
  entryDirectory,
3128
3150
  fsFiles,
3151
+ repoRootPath,
3129
3152
  pythonPath,
3130
3153
  pipPath,
3131
3154
  uvPath,
@@ -3141,6 +3164,7 @@ async function ensureUvProject({
3141
3164
  const { manifestType, manifestPath } = installInfo;
3142
3165
  let projectDir;
3143
3166
  let pyprojectPath;
3167
+ let lockPath = null;
3144
3168
  if (manifestType === "uv.lock") {
3145
3169
  if (!manifestPath) {
3146
3170
  throw new Error("Expected uv.lock path to be resolved, but it was null");
@@ -3152,6 +3176,7 @@ async function ensureUvProject({
3152
3176
  `Expected "pyproject.toml" next to "uv.lock" in "${projectDir}"`
3153
3177
  );
3154
3178
  }
3179
+ lockPath = manifestPath;
3155
3180
  console.log("Installing required dependencies from uv.lock...");
3156
3181
  } else if (manifestType === "pyproject.toml") {
3157
3182
  if (!manifestPath) {
@@ -3162,8 +3187,10 @@ async function ensureUvProject({
3162
3187
  projectDir = (0, import_path2.dirname)(manifestPath);
3163
3188
  pyprojectPath = manifestPath;
3164
3189
  console.log("Installing required dependencies from pyproject.toml...");
3165
- const lockPath2 = (0, import_path2.join)(projectDir, "uv.lock");
3166
- if (!import_fs2.default.existsSync(lockPath2)) {
3190
+ const workspaceLock = findUvLockUpwards(projectDir, repoRootPath);
3191
+ if (workspaceLock) {
3192
+ lockPath = workspaceLock;
3193
+ } else {
3167
3194
  await uvLock({ projectDir, uvPath });
3168
3195
  }
3169
3196
  } else if (manifestType === "Pipfile.lock" || manifestType === "Pipfile") {
@@ -3246,18 +3273,13 @@ async function ensureUvProject({
3246
3273
  });
3247
3274
  }
3248
3275
  }
3249
- const lockPath = (0, import_path2.join)(projectDir, "uv.lock");
3250
- if (!import_fs2.default.existsSync(lockPath)) {
3251
- throw new Error(
3252
- `Expected "uv.lock" to exist in "${projectDir}" after preparing uv project`
3253
- );
3254
- }
3255
- return { projectDir, pyprojectPath, lockPath };
3276
+ const resolvedLockPath = lockPath && import_fs2.default.existsSync(lockPath) ? lockPath : findUvLockUpwards(projectDir, repoRootPath) || (0, import_path2.join)(projectDir, "uv.lock");
3277
+ return { projectDir, pyprojectPath, lockPath: resolvedLockPath };
3256
3278
  }
3257
3279
  async function getGlobalScriptsDir(pythonPath) {
3258
3280
  const code = `import sysconfig; print(sysconfig.get_path('scripts'))`;
3259
3281
  try {
3260
- const { stdout } = await (0, import_execa.default)(pythonPath, ["-c", code]);
3282
+ const { stdout } = await (0, import_execa2.default)(pythonPath, ["-c", code]);
3261
3283
  const out = stdout.trim();
3262
3284
  return out || null;
3263
3285
  } catch (err) {
@@ -3271,7 +3293,7 @@ async function getUserScriptsDir(pythonPath) {
3271
3293
  " "
3272
3294
  );
3273
3295
  try {
3274
- const { stdout } = await (0, import_execa.default)(pythonPath, ["-c", code]);
3296
+ const { stdout } = await (0, import_execa2.default)(pythonPath, ["-c", code]);
3275
3297
  const out = stdout.trim();
3276
3298
  return out || null;
3277
3299
  } catch (err) {
@@ -3295,7 +3317,7 @@ async function pipInstall(pipPath, uvPath, workPath, args, targetDir) {
3295
3317
  const prettyUv = `${uvPath} ${uvArgs.join(" ")}`;
3296
3318
  (0, import_build_utils2.debug)(`Running "${prettyUv}"...`);
3297
3319
  try {
3298
- await (0, import_execa.default)(uvPath, uvArgs, {
3320
+ await (0, import_execa2.default)(uvPath, uvArgs, {
3299
3321
  cwd: workPath
3300
3322
  });
3301
3323
  return;
@@ -3316,7 +3338,7 @@ async function pipInstall(pipPath, uvPath, workPath, args, targetDir) {
3316
3338
  const pretty = `${pipPath} ${cmdArgs.join(" ")}`;
3317
3339
  (0, import_build_utils2.debug)(`Running "${pretty}"...`);
3318
3340
  try {
3319
- await (0, import_execa.default)(pipPath, cmdArgs, {
3341
+ await (0, import_execa2.default)(pipPath, cmdArgs, {
3320
3342
  cwd: workPath
3321
3343
  });
3322
3344
  } catch (err) {
@@ -3373,7 +3395,7 @@ async function getUvBinaryOrInstall(pythonPath) {
3373
3395
  return uvBin;
3374
3396
  try {
3375
3397
  console.log("Installing uv...");
3376
- await (0, import_execa.default)(
3398
+ await (0, import_execa2.default)(
3377
3399
  pythonPath,
3378
3400
  [
3379
3401
  "-m",
@@ -3470,7 +3492,7 @@ async function exportRequirementsFromPipfile({
3470
3492
  (0, import_build_utils2.debug)(`Running "${convertCmd}" in ${projectDir}...`);
3471
3493
  let stdout;
3472
3494
  try {
3473
- const { stdout: out } = await (0, import_execa.default)(convertCmd, [], {
3495
+ const { stdout: out } = await (0, import_execa2.default)(convertCmd, [], {
3474
3496
  cwd: projectDir,
3475
3497
  env: { ...process.env, PYTHONPATH: tempVendorDir }
3476
3498
  });
@@ -4014,14 +4036,14 @@ var startDevServer = async (opts) => {
4014
4036
  let resolveChildReady;
4015
4037
  let rejectChildReady;
4016
4038
  const childReady = new Promise(
4017
- (resolve, reject) => {
4018
- resolveChildReady = resolve;
4039
+ (resolve2, reject) => {
4040
+ resolveChildReady = resolve2;
4019
4041
  rejectChildReady = reject;
4020
4042
  }
4021
4043
  );
4022
4044
  PENDING_STARTS.set(serverKey, childReady);
4023
4045
  try {
4024
- await new Promise((resolve, reject) => {
4046
+ await new Promise((resolve2, reject) => {
4025
4047
  let resolved = false;
4026
4048
  const { pythonPath: systemPython } = getLatestPythonVersion(meta);
4027
4049
  let pythonCmd = systemPython;
@@ -4109,7 +4131,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
4109
4131
  child.stderr?.removeListener("data", onDetect);
4110
4132
  const port2 = Number(portMatch[1]);
4111
4133
  resolveChildReady({ port: port2, pid: child.pid });
4112
- resolve();
4134
+ resolve2();
4113
4135
  }
4114
4136
  }
4115
4137
  };
@@ -4186,7 +4208,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
4186
4208
  child.stderr?.removeListener("data", onDetect);
4187
4209
  const port2 = Number(portMatch[1]);
4188
4210
  resolveChildReady({ port: port2, pid: child.pid });
4189
- resolve();
4211
+ resolve2();
4190
4212
  }
4191
4213
  }
4192
4214
  };
@@ -4248,12 +4270,15 @@ async function downloadFilesInWorkPath({
4248
4270
  }
4249
4271
  var build = async ({
4250
4272
  workPath,
4273
+ repoRootPath,
4251
4274
  files: originalFiles,
4252
4275
  entrypoint,
4253
4276
  meta = {},
4254
4277
  config
4255
4278
  }) => {
4256
4279
  const framework = config?.framework;
4280
+ let spawnEnv;
4281
+ let projectInstallCommand;
4257
4282
  workPath = await downloadFilesInWorkPath({
4258
4283
  workPath,
4259
4284
  files: originalFiles,
@@ -4276,7 +4301,7 @@ var build = async ({
4276
4301
  packageJsonPackageManager,
4277
4302
  turboSupportsCorepackHome
4278
4303
  } = await (0, import_build_utils7.scanParentDirs)(workPath, true);
4279
- const spawnEnv = (0, import_build_utils7.getEnvForPackageManager)({
4304
+ spawnEnv = (0, import_build_utils7.getEnvForPackageManager)({
4280
4305
  cliType,
4281
4306
  lockfileVersion,
4282
4307
  packageJsonPackageManager,
@@ -4286,12 +4311,9 @@ var build = async ({
4286
4311
  });
4287
4312
  const installCommand = config?.projectSettings?.installCommand;
4288
4313
  if (typeof installCommand === "string") {
4289
- if (installCommand.trim()) {
4290
- console.log(`Running "install" command: \`${installCommand}\`...`);
4291
- await (0, import_build_utils7.execCommand)(installCommand, {
4292
- env: spawnEnv,
4293
- cwd: workPath
4294
- });
4314
+ const trimmed = installCommand.trim();
4315
+ if (trimmed) {
4316
+ projectInstallCommand = trimmed;
4295
4317
  } else {
4296
4318
  console.log('Skipping "install" command...');
4297
4319
  }
@@ -4390,34 +4412,63 @@ var build = async ({
4390
4412
  pythonPath: pythonVersion.pythonPath,
4391
4413
  venvPath
4392
4414
  });
4393
- let uvPath;
4394
- try {
4395
- uvPath = await getUvBinaryOrInstall(pythonVersion.pythonPath);
4396
- console.log(`Using uv at "${uvPath}"`);
4397
- } catch (err) {
4398
- console.log("Failed to install or locate uv");
4399
- throw new Error(
4400
- `uv is required for this project but failed to install: ${err instanceof Error ? err.message : String(err)}`
4401
- );
4415
+ const hasCustomInstallCommand = (framework === "fastapi" || framework === "flask") && !!projectInstallCommand;
4416
+ if (hasCustomInstallCommand) {
4417
+ const baseEnv = spawnEnv || process.env;
4418
+ const pythonEnv = createVenvEnv(venvPath, baseEnv);
4419
+ pythonEnv.VERCEL_PYTHON_VENV_PATH = venvPath;
4420
+ const installCommand = projectInstallCommand;
4421
+ console.log(`Running "install" command: \`${installCommand}\`...`);
4422
+ await (0, import_build_utils7.execCommand)(installCommand, {
4423
+ env: pythonEnv,
4424
+ cwd: workPath
4425
+ });
4426
+ } else {
4427
+ let ranPyprojectInstall = false;
4428
+ if (framework === "fastapi" || framework === "flask") {
4429
+ const baseEnv = spawnEnv || process.env;
4430
+ const pythonEnv = createVenvEnv(venvPath, baseEnv);
4431
+ pythonEnv.VERCEL_PYTHON_VENV_PATH = venvPath;
4432
+ ranPyprojectInstall = await runPyprojectScript(
4433
+ workPath,
4434
+ ["vercel-install", "now-install", "install"],
4435
+ pythonEnv,
4436
+ /* useUserVirtualEnv */
4437
+ false
4438
+ );
4439
+ }
4440
+ if (!ranPyprojectInstall) {
4441
+ let uvPath;
4442
+ try {
4443
+ uvPath = await getUvBinaryOrInstall(pythonVersion.pythonPath);
4444
+ console.log(`Using uv at "${uvPath}"`);
4445
+ } catch (err) {
4446
+ console.log("Failed to install or locate uv");
4447
+ throw new Error(
4448
+ `uv is required for this project but failed to install: ${err instanceof Error ? err.message : String(err)}`
4449
+ );
4450
+ }
4451
+ const runtimeDependencies = framework === "flask" ? ["werkzeug>=1.0.1"] : ["werkzeug>=1.0.1", "uvicorn>=0.24"];
4452
+ const { projectDir } = await ensureUvProject({
4453
+ workPath,
4454
+ entryDirectory,
4455
+ fsFiles,
4456
+ repoRootPath,
4457
+ pythonPath: pythonVersion.pythonPath,
4458
+ pipPath: pythonVersion.pipPath,
4459
+ uvPath,
4460
+ venvPath,
4461
+ meta,
4462
+ runtimeDependencies
4463
+ });
4464
+ await runUvSync({
4465
+ uvPath,
4466
+ venvPath,
4467
+ projectDir,
4468
+ locked: true
4469
+ });
4470
+ }
4402
4471
  }
4403
- const runtimeDependencies = framework === "flask" ? ["werkzeug>=1.0.1"] : ["werkzeug>=1.0.1", "uvicorn>=0.24"];
4404
- const { projectDir } = await ensureUvProject({
4405
- workPath,
4406
- entryDirectory,
4407
- fsFiles,
4408
- pythonPath: pythonVersion.pythonPath,
4409
- pipPath: pythonVersion.pipPath,
4410
- uvPath,
4411
- venvPath,
4412
- meta,
4413
- runtimeDependencies
4414
- });
4415
- await runUvSync({
4416
- uvPath,
4417
- venvPath,
4418
- projectDir,
4419
- locked: true
4420
- });
4421
4472
  const originalPyPath = (0, import_path5.join)(__dirname, "..", "vc_init.py");
4422
4473
  const originalHandlerPyContents = await readFile(originalPyPath, "utf8");
4423
4474
  (0, import_build_utils7.debug)("Entrypoint is", entrypoint);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/python",
3
- "version": "6.1.2",
3
+ "version": "6.1.4",
4
4
  "main": "./dist/index.js",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",