@vercel/python 6.1.3 → 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 +102 -71
  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,7 +2854,7 @@ 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
  });
@@ -2897,7 +2899,7 @@ print(spec.origin)
2897
2899
  `;
2898
2900
  async function isInstalled(pythonPath, dependency, cwd) {
2899
2901
  try {
2900
- const { stdout } = await (0, import_execa.default)(
2902
+ const { stdout } = await (0, import_execa2.default)(
2901
2903
  pythonPath,
2902
2904
  ["-c", makeDependencyCheckCode(dependency)],
2903
2905
  {
@@ -2920,7 +2922,7 @@ pkg_resources.require(dependencies)
2920
2922
  `;
2921
2923
  async function areRequirementsInstalled(pythonPath, requirementsPath, cwd) {
2922
2924
  try {
2923
- await (0, import_execa.default)(
2925
+ await (0, import_execa2.default)(
2924
2926
  pythonPath,
2925
2927
  ["-c", makeRequirementsCheckCode(requirementsPath)],
2926
2928
  {
@@ -2940,7 +2942,7 @@ async function runUvSync({
2940
2942
  projectDir,
2941
2943
  locked
2942
2944
  }) {
2943
- const args = ["sync", "--active", "--no-dev"];
2945
+ const args = ["sync", "--active", "--no-dev", "--link-mode", "copy"];
2944
2946
  if (locked) {
2945
2947
  args.push("--locked");
2946
2948
  }
@@ -2963,7 +2965,7 @@ for key in ("purelib", "platlib"):
2963
2965
  paths.append(candidate)
2964
2966
  print(json.dumps(paths))
2965
2967
  `.trim();
2966
- const { stdout } = await (0, import_execa.default)(pythonBin, ["-c", code]);
2968
+ const { stdout } = await (0, import_execa2.default)(pythonBin, ["-c", code]);
2967
2969
  try {
2968
2970
  const parsed = JSON.parse(stdout);
2969
2971
  if (Array.isArray(parsed)) {
@@ -3077,7 +3079,7 @@ async function uvLock({
3077
3079
  const pretty = `${uvPath} ${args.join(" ")}`;
3078
3080
  (0, import_build_utils2.debug)(`Running "${pretty}" in ${projectDir}...`);
3079
3081
  try {
3080
- await (0, import_execa.default)(uvPath, args, { cwd: projectDir });
3082
+ await (0, import_execa2.default)(uvPath, args, { cwd: projectDir });
3081
3083
  } catch (err) {
3082
3084
  throw new Error(
3083
3085
  `Failed to run "${pretty}": ${err instanceof Error ? err.message : String(err)}`
@@ -3130,10 +3132,23 @@ async function filterMissingRuntimeDependencies({
3130
3132
  return !declaredNames.has(name);
3131
3133
  });
3132
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
+ }
3133
3147
  async function ensureUvProject({
3134
3148
  workPath,
3135
3149
  entryDirectory,
3136
3150
  fsFiles,
3151
+ repoRootPath,
3137
3152
  pythonPath,
3138
3153
  pipPath,
3139
3154
  uvPath,
@@ -3149,6 +3164,7 @@ async function ensureUvProject({
3149
3164
  const { manifestType, manifestPath } = installInfo;
3150
3165
  let projectDir;
3151
3166
  let pyprojectPath;
3167
+ let lockPath = null;
3152
3168
  if (manifestType === "uv.lock") {
3153
3169
  if (!manifestPath) {
3154
3170
  throw new Error("Expected uv.lock path to be resolved, but it was null");
@@ -3160,6 +3176,7 @@ async function ensureUvProject({
3160
3176
  `Expected "pyproject.toml" next to "uv.lock" in "${projectDir}"`
3161
3177
  );
3162
3178
  }
3179
+ lockPath = manifestPath;
3163
3180
  console.log("Installing required dependencies from uv.lock...");
3164
3181
  } else if (manifestType === "pyproject.toml") {
3165
3182
  if (!manifestPath) {
@@ -3170,8 +3187,10 @@ async function ensureUvProject({
3170
3187
  projectDir = (0, import_path2.dirname)(manifestPath);
3171
3188
  pyprojectPath = manifestPath;
3172
3189
  console.log("Installing required dependencies from pyproject.toml...");
3173
- const lockPath2 = (0, import_path2.join)(projectDir, "uv.lock");
3174
- if (!import_fs2.default.existsSync(lockPath2)) {
3190
+ const workspaceLock = findUvLockUpwards(projectDir, repoRootPath);
3191
+ if (workspaceLock) {
3192
+ lockPath = workspaceLock;
3193
+ } else {
3175
3194
  await uvLock({ projectDir, uvPath });
3176
3195
  }
3177
3196
  } else if (manifestType === "Pipfile.lock" || manifestType === "Pipfile") {
@@ -3254,18 +3273,13 @@ async function ensureUvProject({
3254
3273
  });
3255
3274
  }
3256
3275
  }
3257
- const lockPath = (0, import_path2.join)(projectDir, "uv.lock");
3258
- if (!import_fs2.default.existsSync(lockPath)) {
3259
- throw new Error(
3260
- `Expected "uv.lock" to exist in "${projectDir}" after preparing uv project`
3261
- );
3262
- }
3263
- 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 };
3264
3278
  }
3265
3279
  async function getGlobalScriptsDir(pythonPath) {
3266
3280
  const code = `import sysconfig; print(sysconfig.get_path('scripts'))`;
3267
3281
  try {
3268
- const { stdout } = await (0, import_execa.default)(pythonPath, ["-c", code]);
3282
+ const { stdout } = await (0, import_execa2.default)(pythonPath, ["-c", code]);
3269
3283
  const out = stdout.trim();
3270
3284
  return out || null;
3271
3285
  } catch (err) {
@@ -3279,7 +3293,7 @@ async function getUserScriptsDir(pythonPath) {
3279
3293
  " "
3280
3294
  );
3281
3295
  try {
3282
- const { stdout } = await (0, import_execa.default)(pythonPath, ["-c", code]);
3296
+ const { stdout } = await (0, import_execa2.default)(pythonPath, ["-c", code]);
3283
3297
  const out = stdout.trim();
3284
3298
  return out || null;
3285
3299
  } catch (err) {
@@ -3303,7 +3317,7 @@ async function pipInstall(pipPath, uvPath, workPath, args, targetDir) {
3303
3317
  const prettyUv = `${uvPath} ${uvArgs.join(" ")}`;
3304
3318
  (0, import_build_utils2.debug)(`Running "${prettyUv}"...`);
3305
3319
  try {
3306
- await (0, import_execa.default)(uvPath, uvArgs, {
3320
+ await (0, import_execa2.default)(uvPath, uvArgs, {
3307
3321
  cwd: workPath
3308
3322
  });
3309
3323
  return;
@@ -3324,7 +3338,7 @@ async function pipInstall(pipPath, uvPath, workPath, args, targetDir) {
3324
3338
  const pretty = `${pipPath} ${cmdArgs.join(" ")}`;
3325
3339
  (0, import_build_utils2.debug)(`Running "${pretty}"...`);
3326
3340
  try {
3327
- await (0, import_execa.default)(pipPath, cmdArgs, {
3341
+ await (0, import_execa2.default)(pipPath, cmdArgs, {
3328
3342
  cwd: workPath
3329
3343
  });
3330
3344
  } catch (err) {
@@ -3381,7 +3395,7 @@ async function getUvBinaryOrInstall(pythonPath) {
3381
3395
  return uvBin;
3382
3396
  try {
3383
3397
  console.log("Installing uv...");
3384
- await (0, import_execa.default)(
3398
+ await (0, import_execa2.default)(
3385
3399
  pythonPath,
3386
3400
  [
3387
3401
  "-m",
@@ -3478,7 +3492,7 @@ async function exportRequirementsFromPipfile({
3478
3492
  (0, import_build_utils2.debug)(`Running "${convertCmd}" in ${projectDir}...`);
3479
3493
  let stdout;
3480
3494
  try {
3481
- const { stdout: out } = await (0, import_execa.default)(convertCmd, [], {
3495
+ const { stdout: out } = await (0, import_execa2.default)(convertCmd, [], {
3482
3496
  cwd: projectDir,
3483
3497
  env: { ...process.env, PYTHONPATH: tempVendorDir }
3484
3498
  });
@@ -4022,14 +4036,14 @@ var startDevServer = async (opts) => {
4022
4036
  let resolveChildReady;
4023
4037
  let rejectChildReady;
4024
4038
  const childReady = new Promise(
4025
- (resolve, reject) => {
4026
- resolveChildReady = resolve;
4039
+ (resolve2, reject) => {
4040
+ resolveChildReady = resolve2;
4027
4041
  rejectChildReady = reject;
4028
4042
  }
4029
4043
  );
4030
4044
  PENDING_STARTS.set(serverKey, childReady);
4031
4045
  try {
4032
- await new Promise((resolve, reject) => {
4046
+ await new Promise((resolve2, reject) => {
4033
4047
  let resolved = false;
4034
4048
  const { pythonPath: systemPython } = getLatestPythonVersion(meta);
4035
4049
  let pythonCmd = systemPython;
@@ -4117,7 +4131,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
4117
4131
  child.stderr?.removeListener("data", onDetect);
4118
4132
  const port2 = Number(portMatch[1]);
4119
4133
  resolveChildReady({ port: port2, pid: child.pid });
4120
- resolve();
4134
+ resolve2();
4121
4135
  }
4122
4136
  }
4123
4137
  };
@@ -4194,7 +4208,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
4194
4208
  child.stderr?.removeListener("data", onDetect);
4195
4209
  const port2 = Number(portMatch[1]);
4196
4210
  resolveChildReady({ port: port2, pid: child.pid });
4197
- resolve();
4211
+ resolve2();
4198
4212
  }
4199
4213
  }
4200
4214
  };
@@ -4256,6 +4270,7 @@ async function downloadFilesInWorkPath({
4256
4270
  }
4257
4271
  var build = async ({
4258
4272
  workPath,
4273
+ repoRootPath,
4259
4274
  files: originalFiles,
4260
4275
  entrypoint,
4261
4276
  meta = {},
@@ -4409,34 +4424,50 @@ var build = async ({
4409
4424
  cwd: workPath
4410
4425
  });
4411
4426
  } else {
4412
- let uvPath;
4413
- try {
4414
- uvPath = await getUvBinaryOrInstall(pythonVersion.pythonPath);
4415
- console.log(`Using uv at "${uvPath}"`);
4416
- } catch (err) {
4417
- console.log("Failed to install or locate uv");
4418
- throw new Error(
4419
- `uv is required for this project but failed to install: ${err instanceof Error ? err.message : String(err)}`
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
4420
4438
  );
4421
4439
  }
4422
- const runtimeDependencies = framework === "flask" ? ["werkzeug>=1.0.1"] : ["werkzeug>=1.0.1", "uvicorn>=0.24"];
4423
- const { projectDir } = await ensureUvProject({
4424
- workPath,
4425
- entryDirectory,
4426
- fsFiles,
4427
- pythonPath: pythonVersion.pythonPath,
4428
- pipPath: pythonVersion.pipPath,
4429
- uvPath,
4430
- venvPath,
4431
- meta,
4432
- runtimeDependencies
4433
- });
4434
- await runUvSync({
4435
- uvPath,
4436
- venvPath,
4437
- projectDir,
4438
- locked: true
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
+ }
4440
4471
  }
4441
4472
  const originalPyPath = (0, import_path5.join)(__dirname, "..", "vc_init.py");
4442
4473
  const originalHandlerPyContents = await readFile(originalPyPath, "utf8");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/python",
3
- "version": "6.1.3",
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",