0

我想从我的 Laravel 控制器运行 Python 脚本 test.py,该脚本在其中导入 Python 模块。起初,在测试 python 脚本在没有它的情况下可以正常工作后,我收到导入到 python 脚本中的 python 包的模块未找到错误。我正在使用 Laravel Sail 和 WSL2。如果我使 test.py 脚本如下:

import sys
    
print(sys.path)

并在我的控制器中运行:

$process = new Process(['python3', app_path('Http/Controllers/test.py'), $content]);
$process->run();

if (!$process->isSuccessful()) {
    throw new ProcessFailedException($process);
}

$result = $process->getOutput();
$path = public_path('temporary/helloworld.txt');
file_put_contents($path, $result);

然后它可以工作并且输出文件有:

['/var/www/html/app/Http/Controllers', '/usr/lib/python39.zip', '/usr/lib/python3.9', '/usr/lib/python3.9/lib-dynload', '/usr/local/lib/python3.9/dist-packages', '/usr/lib/python3/dist-packages']

但是,如果我将 python 脚本更改为导入 Python 模块的脚本,我会收到模块未找到错误(“No module named ..”),即使该模块已安装到虚拟环境。所以我尝试导航到我的项目的根目录,并执行'source tutorial-env/bin/activate'来激活python虚拟环境。然后我做'python''import sys''print(sys.path)'并得到:

 ['', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '/home/username/project-name/tutorial-env/lib/python3.8/site-packages']

所以我很确定问题是 laravel 应用程序使用了错误的 Python 路径。所以我将我的 laravel 控制器更改为:

$process = new Process(['source ' . base_path('tutorial-env/bin/activate') . ' && python3', app_path('Http/Controllers/test.py'), $content]);
$process->run();

if (!$process->isSuccessful()) {
    throw new ProcessFailedException($process);
}

然后我得到错误:命令

"'source /var/www/html/tutorial-env/bin/activate && python3' '/var/www/html/app/Http/Controllers/test.py' 'some text'" failed. Exit Code: 127(Command not found) Working directory: /var/www/html/public Output: ================ Error Output: ================ sh: 1: exec: source /var/www/html/tutorial-env/bin/activate && python3: not found
4

3 回答 3

0

我发现 Process 类的虚拟环境使用了错误的 Python 版本——更改命令python3为我解决了模块导入问题。

于 2021-12-09T09:36:53.393 回答
0

I think you can do something like this in a controller or better in a service :

// src/Controller/monSuperController.php ou mieux dans un service

// use Symfony\Component\Process\Exception\ProcessFailedException;
// use Symfony\Component\Process\Process;

// (...)
$process = new Process(
    [
        '/home/User/path-with-my-python-script/env/bin/python3', 
        '/home/User/path-with-my-python-script/myPythonScript.py',
        '--path', '/home/User/file-path-for-my-python-script/file-for-my-python-script.csv', 
        '--opt1', '1', 
        '--opt2', 'n'
    ]
);


$process->run();
    
// executes after the command finishes
if (!$process->isSuccessful()) {
    throw new ProcessFailedException($process);
}
//you can add a timeout, deactivate python env, kill the process etc in the same way. Have a nice day

// (...)
于 2021-11-24T09:42:53.727 回答
0

您可能必须将命令的每个部分都指定为数组值,如下所示:

$process = new Process(
    [
        'source',
        base_path('tutorial-env/bin/activate'),
        '&&',
        'python3',
        app_path('Http/Controllers/test.py'),
        $content,
     ]
 );

...也python应该python3在虚拟环境中做这个伎俩。

于 2021-09-10T05:33:01.530 回答