使用下面的代码,我可以使用exec从我的sveltekit应用程序运行python脚本.const command = `python "${pythonScriptPath}" ${plateID} "${formattedProdDate}"`; is the 命令,我在其中运行了python脚本.我需要在虚拟环境中运行这个python脚本.

在我的python脚本中,我通过添加一个空的.venv文件夹并运行Pipenv安装创建了一个虚拟环境.当我在目录中时,我运行pipenv run python get-pdf.py string date,它将在虚拟环境中运行python脚本.

所以我试着修改我的sveltekit应用程序const command = `pipenv run python "${pythonScriptPath}" ${plateID} "${formattedProdDate}"中调用脚本的位置 但当我这样做时,它会为我的sveltekit应用程序创建一个虚拟环境,而不是运行我已经安装的虚拟环境.我如何使用已经安装在python脚本所在目录中的虚拟环境来运行python脚本呢?

import fs from 'fs/promises';
import { exec } from 'node:child_process';
import { prisma } from "$lib/server/prisma.js";
import { format } from 'date-fns';

export async function GET({ url }: { url: { searchParams: URLSearchParams } }) {
    const plateID = url.searchParams.get('plateID') || '';

    console.log('Plate id:', plateID);

    // Retrieve production end date from the database
    const prodEndDateRaw = await prisma.$queryRaw<{ PROD_END: Date }[]>`
        SELECT PROD_END 
        FROM LTDB.LTDB.PIECE_TIMES pt 
        WHERE ID_PIECE = ${plateID}
    `;

    // Type casting and null check for prodEndDate
    const prodEndDate = prodEndDateRaw[0]?.PROD_END as Date | undefined;

    if (prodEndDate) {
        // Format production end date
        const formattedProdDate = format(prodEndDate, 'yyyy-MM-dd');
        console.log(formattedProdDate);

        const pythonScriptPath = 'C:\\scripts\\HTLReportScript\\get-pdf.py';

        // Execute the command to run the Python script inside the virtual environment
        const command = `python "${pythonScriptPath}" ${plateID} "${formattedProdDate}"`;

        try {
            console.log('Executing Python script...');
            await new Promise<void>((resolve, reject) => {
                exec(command, (error, stdout, stderr) => {
                    if (error) {
                        console.error(`Error executing Python script: ${error.message}`);
                        console.error('Python script stderr:', stderr);
                        reject(error);
                    } else {
                        console.log('Python script completed:', stdout);
                        resolve();
                    }
                });
            });
        } catch (error: any) {
            console.error('Error:', error.message);
            return createServerErrorResponse('Internal Server Error');
        }

        // Read the file from the local destination
        const localDestination = `C:\\scripts\\HTLReportScript\\Piece_${plateID}.pdf`;
        const fileData = await readFile(localDestination);

        // Set the appropriate headers for the response
        const headers = {
            'Content-Disposition': `attachment; filename=Piece_${plateID}.pdf`,
            'Content-Type': 'application/pdf',
        };

        // Delete the file after sending it to the client
        // await fs.unlink(localDestination);

        // Send the file back to the client
        return new Response(fileData, { headers });
    } else {
        console.error('Error: Production end date not found');
        return createServerErrorResponse('Internal Server Error');
    }
}

async function readFile(filePath: string): Promise<Buffer> {
    try {
        const data = await fs.readFile(filePath);
        return data;
    } catch (error: any) {
        console.error(`Error reading file: ${error.message}`);
        throw new Error('Internal Server Error');
    }
}

function createServerErrorResponse(message: string) {
    return new Response(JSON.stringify({ error: message }), {
        status: 500,
        headers: { 'Content-Type': 'application/json' },
    });
}

-大田美子的解决方案

多亏了美子,我才能把这个修好.我必须通过进入python脚本所在的目录来运行虚拟环境.我决定将我的脚本保存到开发机器和服务器上的C\Script中,这样在将构建移到服务器上时就不必进行任何配置.我更改了const command = `python "${pythonScriptPath}" ${plateID} "${formattedProdDate}"```` to const命令=cd C:\\scripts\\HTLReportScript && C:\\scripts\\HTLReportScript\\.venv\\Scripts\\activate && python get-pdf.py ${plateID} ${formattedProdDate};`这将打开虚拟环境,然后运行python代码.以下是更新后的代码

import fs from 'fs/promises';
import { exec } from 'node:child_process';
import { prisma } from "$lib/server/prisma.js";
import { format } from 'date-fns';

export async function GET({ url }: { url: { searchParams: URLSearchParams } }) {
    const plateID = url.searchParams.get('plateID') || '';

    console.log('Plate id:', plateID);

    // Retrieve production end date from the database
    const prodEndDateRaw = await prisma.$queryRaw<{ PROD_END: Date }[]>`
        SELECT PROD_END 
        FROM LTDB.LTDB.PIECE_TIMES pt 
        WHERE ID_PIECE = ${plateID}
    `;

    // Type casting and null check for prodEndDate
    const prodEndDate = prodEndDateRaw[0]?.PROD_END as Date | undefined;

    if (prodEndDate) {
        // Format production end date
        const formattedProdDate = format(prodEndDate, 'yyyy-MM-dd');
        console.log(formattedProdDate);

        const pythonScriptPath = 'C:\\scripts\\HTLReportScript\\get-pdf.py';

        // Execute the command to run the Python script inside the virtual environment
        const command = `cd C:\\scripts\\HTLReportScript && C:\\scripts\\HTLReportScript\\.venv\\Scripts\\activate && python get-pdf.py ${plateID} ${formattedProdDate}`;

        try {
            console.log('Executing Python script...');
            await new Promise<void>((resolve, reject) => {
                exec(command, (error, stdout, stderr) => {
                    if (error) {
                        console.error(`Error executing Python script: ${error.message}`);
                        console.error('Python script stderr:', stderr);
                        reject(error);
                    } else {
                        console.log('Python script completed:', stdout);
                        resolve();
                    }
                });
            });
        } catch (error: any) {
            console.error('Error:', error.message);
            return createServerErrorResponse('Internal Server Error');
        }

        // Read the file from the local destination
        const localDestination = `C:\\scripts\\HTLReportScript\\Piece_${plateID}.pdf`;
        const fileData = await readFile(localDestination);

        // Set the appropriate headers for the response
        const headers = {
            'Content-Disposition': `attachment; filename=Piece_${plateID}.pdf`,
            'Content-Type': 'application/pdf',
        };

        // Delete the file after sending it to the client
        await fs.unlink(localDestination);

        // Send the file back to the client
        return new Response(fileData, { headers });
    } else {
        console.error('Error: Production end date not found');
        return createServerErrorResponse('Internal Server Error');
    }
}

async function readFile(filePath: string): Promise<Buffer> {
    try {
        const data = await fs.readFile(filePath);
        return data;
    } catch (error: any) {
        console.error(`Error reading file: ${error.message}`);
        throw new Error('Internal Server Error');
    }
}

function createServerErrorResponse(message: string) {
    return new Response(JSON.stringify({ error: message }), {
        status: 500,
        headers: { 'Content-Type': 'application/json' },
    });
}

推荐答案

您可以使用绝对路径在Virtualenv中直接调用python命令.这种方式python始终是正确的虚拟方式.每个Virtualenv在其目录中放置一个新的python二进制文件.

例如,我有

/Users/moo/Library/Caches/pypoetry/virtualenvs/trade-executor-8Oz1GdY1-py3.10/bin/python

我可以通过以下方式在此虚拟环境中运行任何Python脚本:

/Users/moo/Library/Caches/pypoetry/virtualenvs/trade-executor-8Oz1GdY1-py3.10/bin/python myscript.py

希望这能帮上忙.

Python相关问答推荐

将DF中的名称与另一DF拆分并匹配并返回匹配的公司

使用FASTCGI在IIS上运行Django频道

如何在箱形图中添加绘制线的传奇?

如何根据参数推断对象的返回类型?

Pre—Commit MyPy无法禁用非错误消息

Stacked bar chart from billrame

将JSON对象转换为Dataframe

字符串合并语法在哪里记录

在matplotlib中删除子图之间的间隙_mosaic

从Windows Python脚本在WSL上运行Linux应用程序

为什么\b在这个正则表达式中不解释为反斜杠

如何在TensorFlow中分类多个类

如何更改groupby作用域以找到满足掩码条件的第一个值?

为什么'if x is None:pass'比'x is None'单独使用更快?

统计numpy. ndarray中的项目列表出现次数的最快方法

比较两个有条件的数据帧并删除所有不合格的数据帧

大型稀疏CSR二进制矩阵乘法结果中的错误

无法使用请求模块从网页上抓取一些产品的名称

为什么在不先将包作为模块导入的情况下相对导入不起作用

Pandas:使列中的列表大小与另一列中的列表大小相同