@vercel/python 6.11.1 → 6.12.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.
- package/dist/index.js +184 -6
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -2753,7 +2753,7 @@ var import_util = require("util");
|
|
|
2753
2753
|
var import_path7 = require("path");
|
|
2754
2754
|
|
|
2755
2755
|
// src/runtime-version.ts
|
|
2756
|
-
var VERCEL_RUNTIME_VERSION = "0.
|
|
2756
|
+
var VERCEL_RUNTIME_VERSION = "0.4.0";
|
|
2757
2757
|
|
|
2758
2758
|
// src/index.ts
|
|
2759
2759
|
var import_build_utils8 = require("@vercel/build-utils");
|
|
@@ -3070,7 +3070,8 @@ function createVenvEnv(venvPath, baseEnv = process.env) {
|
|
|
3070
3070
|
async function ensureVenv({
|
|
3071
3071
|
pythonPath,
|
|
3072
3072
|
venvPath,
|
|
3073
|
-
uvPath
|
|
3073
|
+
uvPath,
|
|
3074
|
+
quiet
|
|
3074
3075
|
}) {
|
|
3075
3076
|
const marker = (0, import_path3.join)(venvPath, "pyvenv.cfg");
|
|
3076
3077
|
try {
|
|
@@ -3079,7 +3080,9 @@ async function ensureVenv({
|
|
|
3079
3080
|
} catch {
|
|
3080
3081
|
}
|
|
3081
3082
|
await import_fs2.default.promises.mkdir(venvPath, { recursive: true });
|
|
3082
|
-
|
|
3083
|
+
if (!quiet) {
|
|
3084
|
+
console.log(`Creating virtual environment at "${venvPath}"...`);
|
|
3085
|
+
}
|
|
3083
3086
|
if (uvPath) {
|
|
3084
3087
|
await (0, import_execa2.default)(uvPath, ["venv", venvPath]);
|
|
3085
3088
|
} else {
|
|
@@ -3490,6 +3493,12 @@ async function detectInstallSource({
|
|
|
3490
3493
|
});
|
|
3491
3494
|
} catch (error) {
|
|
3492
3495
|
if (error instanceof import_python_analysis.PythonAnalysisError) {
|
|
3496
|
+
if (error.fileContent && (error.code.endsWith("_PARSE_ERROR") || error.code.endsWith("_VALIDATION_ERROR"))) {
|
|
3497
|
+
console.log(
|
|
3498
|
+
`Failed to parse "${error.path}". File content:
|
|
3499
|
+
${error.fileContent}`
|
|
3500
|
+
);
|
|
3501
|
+
}
|
|
3493
3502
|
throw toBuildError(error);
|
|
3494
3503
|
}
|
|
3495
3504
|
throw error;
|
|
@@ -3805,6 +3814,7 @@ async function detectPythonEntrypoint(_framework, workPath, configuredEntrypoint
|
|
|
3805
3814
|
}
|
|
3806
3815
|
|
|
3807
3816
|
// src/start-dev-server.ts
|
|
3817
|
+
var import_python_analysis2 = require("@vercel/python-analysis");
|
|
3808
3818
|
function silenceNodeWarnings() {
|
|
3809
3819
|
const original = process.emitWarning.bind(
|
|
3810
3820
|
process
|
|
@@ -3848,6 +3858,146 @@ function createLogListener(callback, stream) {
|
|
|
3848
3858
|
}
|
|
3849
3859
|
};
|
|
3850
3860
|
}
|
|
3861
|
+
async function syncDependencies({
|
|
3862
|
+
workPath,
|
|
3863
|
+
uvPath,
|
|
3864
|
+
pythonBin,
|
|
3865
|
+
env,
|
|
3866
|
+
onStdout,
|
|
3867
|
+
onStderr
|
|
3868
|
+
}) {
|
|
3869
|
+
const installInfo = await detectInstallSource({
|
|
3870
|
+
workPath,
|
|
3871
|
+
entryDirectory: "."
|
|
3872
|
+
});
|
|
3873
|
+
let { manifestType, manifestPath } = installInfo;
|
|
3874
|
+
const manifest = installInfo.pythonPackage?.manifest;
|
|
3875
|
+
if (!manifestType || !manifestPath) {
|
|
3876
|
+
(0, import_build_utils7.debug)("No Python project manifest found, skipping dependency sync");
|
|
3877
|
+
return;
|
|
3878
|
+
}
|
|
3879
|
+
if (manifest?.origin && manifestType === "pyproject.toml") {
|
|
3880
|
+
const syncDir = (0, import_path6.join)(workPath, ".vercel", "python", "sync");
|
|
3881
|
+
(0, import_fs4.mkdirSync)(syncDir, { recursive: true });
|
|
3882
|
+
const tempPyproject = (0, import_path6.join)(syncDir, "pyproject.toml");
|
|
3883
|
+
const content = (0, import_python_analysis2.stringifyManifest)(manifest.data);
|
|
3884
|
+
(0, import_fs4.writeFileSync)(tempPyproject, content, "utf8");
|
|
3885
|
+
manifestPath = tempPyproject;
|
|
3886
|
+
(0, import_build_utils7.debug)(
|
|
3887
|
+
`Wrote converted ${manifest.origin.kind} manifest to ${tempPyproject}`
|
|
3888
|
+
);
|
|
3889
|
+
}
|
|
3890
|
+
const writeOut = (msg) => {
|
|
3891
|
+
if (onStdout) {
|
|
3892
|
+
onStdout(Buffer.from(msg));
|
|
3893
|
+
} else {
|
|
3894
|
+
process.stdout.write(msg);
|
|
3895
|
+
}
|
|
3896
|
+
};
|
|
3897
|
+
const writeErr = (msg) => {
|
|
3898
|
+
if (onStderr) {
|
|
3899
|
+
onStderr(Buffer.from(msg));
|
|
3900
|
+
} else {
|
|
3901
|
+
process.stderr.write(msg);
|
|
3902
|
+
}
|
|
3903
|
+
};
|
|
3904
|
+
const captured = [];
|
|
3905
|
+
try {
|
|
3906
|
+
await runSync({
|
|
3907
|
+
manifestType,
|
|
3908
|
+
manifestPath,
|
|
3909
|
+
uvPath,
|
|
3910
|
+
pythonBin,
|
|
3911
|
+
env,
|
|
3912
|
+
onStdout: (data) => captured.push(["stdout", data]),
|
|
3913
|
+
onStderr: (data) => captured.push(["stderr", data])
|
|
3914
|
+
});
|
|
3915
|
+
} catch (err) {
|
|
3916
|
+
for (const [channel, chunk] of captured) {
|
|
3917
|
+
(channel === "stdout" ? writeOut : writeErr)(chunk.toString());
|
|
3918
|
+
}
|
|
3919
|
+
throw new import_build_utils7.NowBuildError({
|
|
3920
|
+
code: "PYTHON_DEPENDENCY_SYNC_FAILED",
|
|
3921
|
+
message: `Failed to install Python dependencies from ${manifestType}: ${err instanceof Error ? err.message : String(err)}`
|
|
3922
|
+
});
|
|
3923
|
+
}
|
|
3924
|
+
}
|
|
3925
|
+
async function runSync({
|
|
3926
|
+
manifestType,
|
|
3927
|
+
manifestPath,
|
|
3928
|
+
uvPath,
|
|
3929
|
+
pythonBin,
|
|
3930
|
+
env,
|
|
3931
|
+
onStdout,
|
|
3932
|
+
onStderr
|
|
3933
|
+
}) {
|
|
3934
|
+
const projectDir = (0, import_path6.dirname)(manifestPath);
|
|
3935
|
+
const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
|
|
3936
|
+
let spawnCmd;
|
|
3937
|
+
let spawnArgs;
|
|
3938
|
+
switch (manifestType) {
|
|
3939
|
+
case "uv.lock": {
|
|
3940
|
+
if (!uvPath) {
|
|
3941
|
+
throw new import_build_utils7.NowBuildError({
|
|
3942
|
+
code: "PYTHON_DEPENDENCY_SYNC_FAILED",
|
|
3943
|
+
message: "uv is required to install dependencies from uv.lock.",
|
|
3944
|
+
link: "https://docs.astral.sh/uv/getting-started/installation/",
|
|
3945
|
+
action: "Install uv"
|
|
3946
|
+
});
|
|
3947
|
+
}
|
|
3948
|
+
spawnCmd = uvPath;
|
|
3949
|
+
spawnArgs = ["sync"];
|
|
3950
|
+
break;
|
|
3951
|
+
}
|
|
3952
|
+
case "pylock.toml": {
|
|
3953
|
+
spawnCmd = pip.cmd;
|
|
3954
|
+
spawnArgs = [...pip.prefix, "-r", manifestPath];
|
|
3955
|
+
break;
|
|
3956
|
+
}
|
|
3957
|
+
case "pyproject.toml": {
|
|
3958
|
+
spawnCmd = pip.cmd;
|
|
3959
|
+
spawnArgs = [...pip.prefix, projectDir];
|
|
3960
|
+
break;
|
|
3961
|
+
}
|
|
3962
|
+
default:
|
|
3963
|
+
(0, import_build_utils7.debug)(`Unknown manifest type: ${manifestType}`);
|
|
3964
|
+
return;
|
|
3965
|
+
}
|
|
3966
|
+
await new Promise((resolve, reject) => {
|
|
3967
|
+
(0, import_build_utils7.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
|
|
3968
|
+
const child = (0, import_child_process2.spawn)(spawnCmd, spawnArgs, {
|
|
3969
|
+
cwd: projectDir,
|
|
3970
|
+
env: getProtectedUvEnv(env),
|
|
3971
|
+
stdio: ["inherit", "pipe", "pipe"]
|
|
3972
|
+
});
|
|
3973
|
+
child.stdout?.on("data", (data) => {
|
|
3974
|
+
if (onStdout) {
|
|
3975
|
+
onStdout(data);
|
|
3976
|
+
} else {
|
|
3977
|
+
process.stdout.write(data.toString());
|
|
3978
|
+
}
|
|
3979
|
+
});
|
|
3980
|
+
child.stderr?.on("data", (data) => {
|
|
3981
|
+
if (onStderr) {
|
|
3982
|
+
onStderr(data);
|
|
3983
|
+
} else {
|
|
3984
|
+
process.stderr.write(data.toString());
|
|
3985
|
+
}
|
|
3986
|
+
});
|
|
3987
|
+
child.on("error", reject);
|
|
3988
|
+
child.on("exit", (code, signal) => {
|
|
3989
|
+
if (code === 0) {
|
|
3990
|
+
resolve();
|
|
3991
|
+
} else {
|
|
3992
|
+
reject(
|
|
3993
|
+
new Error(
|
|
3994
|
+
`Command "${spawnCmd} ${spawnArgs.join(" ")}" failed with code ${code}, signal ${signal}`
|
|
3995
|
+
)
|
|
3996
|
+
);
|
|
3997
|
+
}
|
|
3998
|
+
});
|
|
3999
|
+
});
|
|
4000
|
+
}
|
|
3851
4001
|
var PERSISTENT_SERVERS = /* @__PURE__ */ new Map();
|
|
3852
4002
|
var PENDING_STARTS = /* @__PURE__ */ new Map();
|
|
3853
4003
|
var restoreWarnings = null;
|
|
@@ -3928,7 +4078,7 @@ async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath)
|
|
|
3928
4078
|
return { command: pythonCmd, args: [] };
|
|
3929
4079
|
}
|
|
3930
4080
|
const venvPath = (0, import_path6.join)(workPath, ".venv");
|
|
3931
|
-
await ensureVenv({ pythonPath: systemPython, venvPath, uvPath });
|
|
4081
|
+
await ensureVenv({ pythonPath: systemPython, venvPath, uvPath, quiet: true });
|
|
3932
4082
|
(0, import_build_utils7.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
|
|
3933
4083
|
const pythonBin = getVenvPythonBin(venvPath);
|
|
3934
4084
|
const binDir = getVenvBinDir(venvPath);
|
|
@@ -4058,6 +4208,25 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
4058
4208
|
}
|
|
4059
4209
|
}
|
|
4060
4210
|
}
|
|
4211
|
+
if (meta.syncDependencies) {
|
|
4212
|
+
const gray = "\x1B[90m";
|
|
4213
|
+
const reset = "\x1B[0m";
|
|
4214
|
+
const syncMessage = `${gray}Synchronizing dependencies...${reset}
|
|
4215
|
+
`;
|
|
4216
|
+
if (onStdout) {
|
|
4217
|
+
onStdout(Buffer.from(syncMessage));
|
|
4218
|
+
} else {
|
|
4219
|
+
console.log(syncMessage);
|
|
4220
|
+
}
|
|
4221
|
+
await syncDependencies({
|
|
4222
|
+
workPath,
|
|
4223
|
+
uvPath,
|
|
4224
|
+
pythonBin: spawnCommand,
|
|
4225
|
+
env,
|
|
4226
|
+
onStdout,
|
|
4227
|
+
onStderr
|
|
4228
|
+
});
|
|
4229
|
+
}
|
|
4061
4230
|
await new Promise((resolve, reject) => {
|
|
4062
4231
|
let resolved = false;
|
|
4063
4232
|
if (framework !== "flask") {
|
|
@@ -4372,9 +4541,18 @@ var build = async ({
|
|
|
4372
4541
|
}
|
|
4373
4542
|
if (!declaredPythonVersion && pipfileLockDir) {
|
|
4374
4543
|
let lock = {};
|
|
4544
|
+
const pipfileLockPath = (0, import_path7.join)(pipfileLockDir, "Pipfile.lock");
|
|
4375
4545
|
try {
|
|
4376
|
-
const
|
|
4377
|
-
|
|
4546
|
+
const pipfileLockContent = await readFile(pipfileLockPath, "utf8");
|
|
4547
|
+
try {
|
|
4548
|
+
lock = JSON.parse(pipfileLockContent);
|
|
4549
|
+
} catch (err) {
|
|
4550
|
+
console.log(
|
|
4551
|
+
`Failed to parse "Pipfile.lock". File content:
|
|
4552
|
+
${pipfileLockContent}`
|
|
4553
|
+
);
|
|
4554
|
+
throw err;
|
|
4555
|
+
}
|
|
4378
4556
|
} catch (err) {
|
|
4379
4557
|
throw new import_build_utils8.NowBuildError({
|
|
4380
4558
|
code: "INVALID_PIPFILE_LOCK",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/python",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.12.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"directory": "packages/python"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@vercel/python-analysis": "0.4.
|
|
19
|
+
"@vercel/python-analysis": "0.4.1"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@renovatebot/pep440": "4.2.1",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"smol-toml": "1.5.2",
|
|
35
35
|
"vitest": "2.1.4",
|
|
36
36
|
"which": "3.0.0",
|
|
37
|
-
"@vercel/build-utils": "13.
|
|
37
|
+
"@vercel/build-utils": "13.4.0",
|
|
38
38
|
"@vercel/error-utils": "2.0.3"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|