使用下面的代码,我可以使用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' },
});
}