@vercel/python 26.0.1 → 27.0.0

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 +85 -93
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -9415,7 +9415,7 @@ async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath)
9415
9415
  env.PATH = `${binDir}${import_path13.delimiter}${env.PATH || ""}`;
9416
9416
  return { command: pythonBin, args: [] };
9417
9417
  }
9418
- async function getPersistentServer(serverKey, isStale) {
9418
+ async function claimPersistentServer(serverKey, isStale) {
9419
9419
  while (true) {
9420
9420
  const existing = PERSISTENT_SERVERS.get(serverKey);
9421
9421
  if (existing) {
@@ -9432,9 +9432,19 @@ async function getPersistentServer(serverKey, isStale) {
9432
9432
  }
9433
9433
  const pending = PENDING_STARTS.get(serverKey);
9434
9434
  if (!pending)
9435
- return null;
9435
+ break;
9436
9436
  await pending;
9437
9437
  }
9438
+ let start;
9439
+ const ready = new Promise(
9440
+ (resolve4, reject) => {
9441
+ start = { resolve: resolve4, reject };
9442
+ }
9443
+ );
9444
+ ready.catch(() => {
9445
+ });
9446
+ PENDING_STARTS.set(serverKey, ready);
9447
+ return start;
9438
9448
  }
9439
9449
  async function spawnPersistentServer({
9440
9450
  serverKey,
@@ -9546,31 +9556,22 @@ var startProxyDevServer = async ({
9546
9556
  );
9547
9557
  }
9548
9558
  const serverKey = `${workPath}::proxy::${entrypoint}`;
9549
- const existing = await getPersistentServer(serverKey);
9550
- if (existing) {
9551
- return existing;
9559
+ const start = await claimPersistentServer(serverKey);
9560
+ if ("port" in start) {
9561
+ return start;
9552
9562
  }
9553
9563
  if (!restoreWarnings)
9554
9564
  restoreWarnings = silenceNodeWarnings();
9555
9565
  installGlobalCleanupHandlers();
9556
- const proxySource = (0, import_fs13.readFileSync)((0, import_path13.join)(workPath, entrypoint), "utf8");
9557
- if (!await (0, import_python_analysis9.containsTopLevelCallable)(proxySource, handlerFunction)) {
9558
- throw new import_build_utils15.NowBuildError({
9559
- code: "PYTHON_HANDLER_NOT_FOUND",
9560
- message: `Handler function "${handlerFunction}" not found in ${entrypoint}. Ensure it is defined at the module's top level.`
9561
- });
9562
- }
9563
9566
  const env = { ...process.env, ...meta.env || {} };
9564
- let resolveChildReady;
9565
- let rejectChildReady;
9566
- const childReady = new Promise(
9567
- (resolve4, reject) => {
9568
- resolveChildReady = resolve4;
9569
- rejectChildReady = reject;
9570
- }
9571
- );
9572
- PENDING_STARTS.set(serverKey, childReady);
9573
9567
  try {
9568
+ const proxySource = (0, import_fs13.readFileSync)((0, import_path13.join)(workPath, entrypoint), "utf8");
9569
+ if (!await (0, import_python_analysis9.containsTopLevelCallable)(proxySource, handlerFunction)) {
9570
+ throw new import_build_utils15.NowBuildError({
9571
+ code: "PYTHON_HANDLER_NOT_FOUND",
9572
+ message: `Handler function "${handlerFunction}" not found in ${entrypoint}. Ensure it is defined at the module's top level.`
9573
+ });
9574
+ }
9574
9575
  const { pythonPath: systemPython } = getDefaultPythonVersion(meta);
9575
9576
  const uvPath = await findUvBinary(systemPython);
9576
9577
  if (uvPath) {
@@ -9624,11 +9625,11 @@ var startProxyDevServer = async ({
9624
9625
  onStdout,
9625
9626
  onStderr
9626
9627
  });
9627
- resolveChildReady({ port, pid });
9628
+ start.resolve({ port, pid });
9628
9629
  return { port, pid, shutdown: async () => {
9629
9630
  } };
9630
9631
  } catch (err) {
9631
- rejectChildReady(err);
9632
+ start.reject(err);
9632
9633
  throw err;
9633
9634
  } finally {
9634
9635
  PENDING_STARTS.delete(serverKey);
@@ -9655,83 +9656,74 @@ var startDevServer = async (opts) => {
9655
9656
  const scheduleEnv = scheduleFunction ? { ...env } : void 0;
9656
9657
  const serviceName = service?.name ?? (typeof meta.serviceName === "string" ? meta.serviceName : void 0);
9657
9658
  const serverKey = scheduleFunction ? `${workPath}::schedule::${scheduleFunction.outputPath}` : serviceName ? `${workPath}::${framework}::${serviceName}` : `${workPath}::${framework}`;
9658
- const existing = await getPersistentServer(
9659
+ if (!framework && !scheduleFunction) {
9660
+ return null;
9661
+ }
9662
+ const start = await claimPersistentServer(
9659
9663
  serverKey,
9660
9664
  (info) => !!scheduleFunction && (info.scheduleModule !== scheduleModule || !(0, import_util2.isDeepStrictEqual)(info.scheduleEnv, scheduleEnv))
9661
9665
  );
9662
- if (existing) {
9663
- return existing;
9664
- }
9665
- if (!framework && !scheduleFunction) {
9666
- return null;
9666
+ if ("port" in start) {
9667
+ return start;
9667
9668
  }
9668
9669
  if (!restoreWarnings)
9669
9670
  restoreWarnings = silenceNodeWarnings();
9670
9671
  installGlobalCleanupHandlers();
9671
- const entrypoint = rawEntrypoint === "<detect>" ? void 0 : rawEntrypoint;
9672
- const isPyprojectEntrypoint = entrypoint === "pyproject.toml";
9673
- let resolved;
9674
- const handlerFunction = typeof config?.handlerFunction === "string" ? config.handlerFunction : void 0;
9675
- const isPyQueueSidecar = config?.pythonQueueSidecar === "subscriber" || config?.pythonQueueSidecar === "workflow";
9676
- let detected;
9677
- if (scheduleHandlerPath && scheduleModule) {
9678
- const entrypoint2 = import_path13.posix.join(".vercel/python", scheduleHandlerPath);
9679
- (0, import_fs13.mkdirSync)((0, import_path13.dirname)((0, import_path13.join)(workPath, entrypoint2)), { recursive: true });
9680
- (0, import_fs13.writeFileSync)((0, import_path13.join)(workPath, entrypoint2), scheduleModule);
9681
- detected = { entrypoint: { entrypoint: entrypoint2, variableName: "app" } };
9682
- } else if (isPyprojectEntrypoint) {
9683
- const declaredEntrypoint = await getVercelToolsEntrypoint(
9684
- workPath,
9685
- opts.repoRootPath
9686
- );
9687
- detected = declaredEntrypoint ? { entrypoint: declaredEntrypoint } : null;
9688
- } else {
9689
- detected = await detectPythonEntrypoint(
9690
- framework,
9691
- workPath,
9692
- entrypoint ? {
9693
- filePath: entrypoint,
9694
- // Schedule-triggered services create their own "app" wrapper dynamically.
9695
- // Other services use handlerFunction as the entrypoint variable name.
9696
- varName: service && (0, import_build_utils15.isScheduleTriggeredService)(service) ? void 0 : handlerFunction ?? (isPyQueueSidecar ? "app" : void 0)
9697
- } : void 0,
9698
- service,
9699
- opts.repoRootPath
9700
- );
9701
- }
9702
- let hookResult;
9703
- if (detected?.entrypoint) {
9704
- resolved = detected.entrypoint;
9705
- } else if (!isPyprojectEntrypoint) {
9706
- hookResult = await runFrameworkHook(framework, {
9707
- pythonEnv: env,
9708
- workPath,
9709
- entrypoint,
9710
- detected: detected ?? void 0
9711
- });
9712
- resolved = hookResult?.entrypoint;
9713
- }
9714
- if (!resolved) {
9715
- if (detected?.error) {
9716
- throw detected.error;
9672
+ try {
9673
+ const entrypoint = rawEntrypoint === "<detect>" ? void 0 : rawEntrypoint;
9674
+ const isPyprojectEntrypoint = entrypoint === "pyproject.toml";
9675
+ let resolved;
9676
+ const handlerFunction = typeof config?.handlerFunction === "string" ? config.handlerFunction : void 0;
9677
+ const isPyQueueSidecar = config?.pythonQueueSidecar === "subscriber" || config?.pythonQueueSidecar === "workflow";
9678
+ let detected;
9679
+ if (scheduleHandlerPath && scheduleModule) {
9680
+ const entrypoint2 = import_path13.posix.join(".vercel/python", scheduleHandlerPath);
9681
+ (0, import_fs13.mkdirSync)((0, import_path13.dirname)((0, import_path13.join)(workPath, entrypoint2)), { recursive: true });
9682
+ (0, import_fs13.writeFileSync)((0, import_path13.join)(workPath, entrypoint2), scheduleModule);
9683
+ detected = { entrypoint: { entrypoint: entrypoint2, variableName: "app" } };
9684
+ } else if (isPyprojectEntrypoint) {
9685
+ const declaredEntrypoint = await getVercelToolsEntrypoint(
9686
+ workPath,
9687
+ opts.repoRootPath
9688
+ );
9689
+ detected = declaredEntrypoint ? { entrypoint: declaredEntrypoint } : null;
9690
+ } else {
9691
+ detected = await detectPythonEntrypoint(
9692
+ framework,
9693
+ workPath,
9694
+ entrypoint ? {
9695
+ filePath: entrypoint,
9696
+ // Schedule-triggered services create their own "app" wrapper dynamically.
9697
+ // Other services use handlerFunction as the entrypoint variable name.
9698
+ varName: service && (0, import_build_utils15.isScheduleTriggeredService)(service) ? void 0 : handlerFunction ?? (isPyQueueSidecar ? "app" : void 0)
9699
+ } : void 0,
9700
+ service,
9701
+ opts.repoRootPath
9702
+ );
9717
9703
  }
9718
- throw new import_build_utils15.NowBuildError({
9719
- code: isPyprojectEntrypoint ? "PYTHON_PYPROJECT_NOTHING_TO_BUILD" : "PYTHON_ENTRYPOINT_NOT_FOUND",
9720
- message: isPyprojectEntrypoint ? 'Entrypoint "pyproject.toml" does not declare a web app. Set "tool.vercel.entrypoint" in pyproject.toml.' : "No Python entrypoint could be detected. Please specify an entrypoint file."
9721
- });
9722
- }
9723
- const { entrypoint: entry, variableName } = resolved;
9724
- const modulePath = scheduleHandlerPath ? generatedPythonPathToModule(scheduleHandlerPath) : entrypointToModule(entry);
9725
- let resolveChildReady;
9726
- let rejectChildReady;
9727
- const childReady = new Promise(
9728
- (resolve4, reject) => {
9729
- resolveChildReady = resolve4;
9730
- rejectChildReady = reject;
9704
+ let hookResult;
9705
+ if (detected?.entrypoint) {
9706
+ resolved = detected.entrypoint;
9707
+ } else if (!isPyprojectEntrypoint) {
9708
+ hookResult = await runFrameworkHook(framework, {
9709
+ pythonEnv: env,
9710
+ workPath,
9711
+ entrypoint,
9712
+ detected: detected ?? void 0
9713
+ });
9714
+ resolved = hookResult?.entrypoint;
9731
9715
  }
9732
- );
9733
- PENDING_STARTS.set(serverKey, childReady);
9734
- try {
9716
+ if (!resolved) {
9717
+ if (detected?.error) {
9718
+ throw detected.error;
9719
+ }
9720
+ throw new import_build_utils15.NowBuildError({
9721
+ code: isPyprojectEntrypoint ? "PYTHON_PYPROJECT_NOTHING_TO_BUILD" : "PYTHON_ENTRYPOINT_NOT_FOUND",
9722
+ message: isPyprojectEntrypoint ? 'Entrypoint "pyproject.toml" does not declare a web app. Set "tool.vercel.entrypoint" in pyproject.toml.' : "No Python entrypoint could be detected. Please specify an entrypoint file."
9723
+ });
9724
+ }
9725
+ const { entrypoint: entry, variableName } = resolved;
9726
+ const modulePath = scheduleHandlerPath ? generatedPythonPathToModule(scheduleHandlerPath) : entrypointToModule(entry);
9735
9727
  const { pythonPath: systemPython } = getDefaultPythonVersion(meta);
9736
9728
  const uvPath = await findUvBinary(systemPython);
9737
9729
  if (uvPath) {
@@ -9989,12 +9981,12 @@ If you are using a virtual environment, activate it before running "vercel dev",
9989
9981
  scheduleModule,
9990
9982
  scheduleEnv
9991
9983
  });
9992
- resolveChildReady({ port, pid });
9984
+ start.resolve({ port, pid });
9993
9985
  const shutdown = async () => {
9994
9986
  };
9995
9987
  return { port, pid, shutdown, crons, queueSubscriptions };
9996
9988
  } catch (err) {
9997
- rejectChildReady(err);
9989
+ start.reject(err);
9998
9990
  throw err;
9999
9991
  } finally {
10000
9992
  PENDING_STARTS.delete(serverKey);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/python",
3
- "version": "26.0.1",
3
+ "version": "27.0.0",
4
4
  "main": "./dist/index.js",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
@@ -14,10 +14,10 @@
14
14
  "directory": "packages/python"
15
15
  },
16
16
  "dependencies": {
17
- "@vercel/python-analysis": "0.15.1"
17
+ "@vercel/python-analysis": "0.15.2"
18
18
  },
19
19
  "peerDependencies": {
20
- "@vercel/build-utils": "14.22.0"
20
+ "@vercel/build-utils": "14.23.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@renovatebot/pep440": "4.2.1",
@@ -37,7 +37,7 @@
37
37
  "smol-toml": "1.5.2",
38
38
  "vitest": "4.1.10",
39
39
  "which": "3.0.0",
40
- "@vercel/build-utils": "14.22.0",
40
+ "@vercel/build-utils": "14.23.0",
41
41
  "@vercel/error-utils": "2.2.1",
42
42
  "@vercel/python-runtime": "0.23.3"
43
43
  },