Run python from laravel - python

I'm trying to run a python script from Laravel, with Symfony Process component like this :
My controller :
public function access(Request $request)
{
$process = new Process(['test.py', 'helloworld']);
$process->run();
dd($process->getOutput());
}
Python script :
import sys
x = sys.argv[1]
print(x)
But all i get in dd is ""
What do you think is the problem ?

Not an answer, just a tip but too long to fit as a comment:
Instead of dumping only the standard output, you can dump as well other useful information:
$process = new Process(['/usr/bin/python', '/my/full/path/test.py', 'helloworld']);
$process->run();
echo "Output:\n";
dump($process->getOutput());
echo "Error:\n";
dump($process->getErrorOutput());
echo "Exit code: " . $process->getExitCode() . "\n";
die;

Symfony process keeps throwing Fatal Python error: _Py_HashRandomization_Init error, used shell_exec() instead.
<?php
$var = "Hello World";
$command = escapeshellcmd('path_to_python_script.py '.$var);
$output = shell_exec($command);
echo $output;
?>
you can also send file instead of variable and have it handled from python. if you want to get runtime inputs checkout Brython or Skulpt.

Related

How to run a Python script from PHP

I need to run a python script from php.. Here is my try..
<?php
if (isset($_POST['action'])) {
switch ($_POST['action']) {
case 'Run_Python':
Run_Python();
break;
case 'Run_Python2':
Run_Python2();
break;
}
}
function Run_Python() {
$output = shell_exec("/root/anaconda3/envs/py36/bin/python3 /home/scripts/test.py");
echo $output;
exit;
}
}
This action is combined with a button...But I am not getting any output from this..
Note:
Here is a separate bash script which uses to run set of python scripts.This works fine.. Am I doing any wrong with the libraries?
#!/bin/bash
cd /home/scripts/
export PATH="/root/anaconda3/envs/py36/bin:/usr/share/Modules/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin"
export TEMP=/home/svradmin/tmp
python3 test.py

Running a python script from a php backend [duplicate]

I want to execute Python script from PHP file. I am able to execute simple python script like:
print("Hello World")
but when I want to execute following script, nothing happens
from pydub import AudioSegment
AudioSegment.converter = "/usr/bin/ffmpeg"
sound = AudioSegment.from_file("/var/www/dev.com/public_html/track.mp3")
sound.export("/var/www/dev.com/public_html/test.mp3", format="mp3", bitrate="96k")
and same script works fine when I execute it from terminal. here is my php script:
$output = shell_exec("/usr/bin/python /var/www/dev.com/public_html/index.py");
echo $output;
I have also tried following method but no luck:
$output = array();
$output = passthru("/usr/bin/python /var/www/dev.com/public_html/index.py");
print_r($output);
please help me
PHP's passthru function does not have the elegant method for which you may be searching of passing environment variables. If you must use passthru, then export your variables directly in the command:
passthru("SOMEVAR=$yourVar PATH=$newPATH ... /path/to/executable $arg1 $arg2 ...")
If you are inclined toward shell_exec, you may appreciate putenv for the slightly cleaner interface:
putenv("SOMEVAR=$yourVar");
putenv("PATH=$newPATH");
echo shell_exec("/path/to/executable $arg1 $arg2 ...");
If you are open to a more robust (if tedious) approach, consider proc_open:
$cmd = "/path/to/executable arg1 arg2 ..."
# Files 0, 1, 2 are the standard "stdin", "stdout", and "stderr"; For details
# read the PHP docs on proc_open. The key here is to give the child process a
# pipe to write to, and from which we will read and handle the "passthru"
# ourselves
$fileDescriptors = array(
0 => ["pipe", "r"],
1 => ["pipe", "w"],
2 => ["pipe", "w"]
);
$cwd = '/tmp';
$env = [
'PATH' => $newPATH,
'SOMEVAR' => $someVar,
...
];
# "pHandle" = "Process handle". Note that $pipes is new here, and will be
# given back to us
$pHandle = proc_open($cmd, $fileDescriptors, $pipes, $cwd, $env);
# crucial: did proc_open work?
if ( is_resource( $pHandle ) ) {
# $pipes is now valid
$pstdout = $pipes[ 1 ];
# Hey, whaddya know? PHP has just what we need...
fpassthru( $pstdout );
# Whenever you proc_open, you must also proc_close. Just don't
# forget to close any open file handles
fclose( $pipes[0] );
fclose( $pipes[1] );
fclose( $pipes[2] );
proc_close( $pHandle );
}
Acc to your reply, as you want to execute the python script from PHP
I was able to execute it using the following code
$command = escapeshellcmd('/var/www/yourscript.py');
$output = shell_exec($command);
echo $output;
Please use the above PHP code with the same python script.
Try to run the python script as a GCI script first to make sure it is working and set the permissions to public directory and script as I mentioned before
===================old ans============================
From what you asked, I guess this is what you are trying to do is that you are trying to run it as a CGI script like http://localhost/yourscript.py
And why are you using PHP to execute python script when you can run it directly as a CGI script?
here is what you need to do to make it work like a web page:
enable python CGI in apache ( or in the web server you are using ).
put the script in CGI configured directory
add proper code to your script to make it work as a CGI script
#!/usr/local/bin/python
from pydub import AudioSegment
AudioSegment.converter = "/usr/local/bin/ffmpeg"
sound = AudioSegment.from_file("/var/www/dev.com/public_html/track.mp3")
sound.export("/var/www/dev.com/public_html/test.mp3", format="mp3", bitrate="96k")
print "Content-type: text/html"
print
print ""
print ""
print ""
print "Done/ you can perform some conditions and print useful info here"
print ""
Give permissions to the script and make the public directory writable
Access the script http://localhost/your-path-to-script.py
I was able to run this properly.
let me know if that's not your case if you want something else
In my case, I did this code.
<?php
chdir('/home/pythontest') ; // python code dir
$commandline="/usr/bin/python3 test.py parameter" ;
exec($commandline, $output, $error) ;
echo $output ;
?>
If you need to set some environments for python, add environment vars like this.
$commmandline="LANG=en_US.utf8 LC_ALL=en_US.utf8 /usr/bin/python3 ..." ;
and check the httpd log.
Check this:
The apache user has to be in sudoers file, better you don't give sudo to apache instead give apache (www-data) user right to run your python program
put first line in your python script: #!/usr/bin/env python so the script knows which program to open it with..
then,
change group:
chgrp www-data /path/to/python-script.py
make it executabe:
chmod +x /path/to/python-script.py
then try it:
shell_exec("/path/to/python-script.py");
I hope this will work! :)
You can also exec ffmpeg directly without python:
$output = shell_exec("/usr/bin/ffmpeg -i in.mp3 -b:a 96k out.mp3");
echo $output;
ffmpeg docs
Answered in 2022.
In php 8.0 and above the following method worked. Above answers are very useful but i am compiling few extra steps here.
PHP Code.
$output = shell_exec("python3 /var/www/python/test.py");
print_r($output);
exec('python3 --version 2>&1', $output);
var_dump($output);
Trying both shell_exe and exec
Make sure the python file has executable permission and added to www-data group (if its ubuntu/debian systems) . sudo chmod +x test.py and sudo chgrp www-data test.py
Make sure the php.ini has disabled_functions line commented or empty.
sudo vim sudo vim /etc/php/8.0/cli/php.ini
sudo vim sudo vim /etc/php/8.0/apache2/php.ini
For both.
I compiled a simple video to make sure others dont spend more time figuring out the problem. https://youtu.be/t-f6b71jyoM

Why my Python script is not communicating with the PHP(shell_exec)?

I'm trying to run shell_exec in my index.php for executing hello.py.
The problem is that the hello.py does not seems to receive my variables from the index.php. I can't really find out whats the error is. I'm thinking that there's a problem with the shell_exec
index.php :
<?php
$output = shell_exec('python hello.py "Person" 0');
echo $output;
?>
hello.py:
import sys
name = sys.argv[1]
age = sys.argv[2]
print("Hello my name is",name,"and I'm",age,"years old")

Executing Python script via Laravel controller

It may be a simple question but i could not find a solution that works for me properly. So i want to start a python skript via a controller in laravel. So far i tried exec(), shell_exec() and this as well:
$cmd = "py pathtoSkript/example.py";
if (substr(php_uname(), 0, 7) == "Windows"){
pclose(popen("start /B ". $cmd, "r"));
}
else {
exec($cmd . " > /dev/null &");
}
My python Version is: Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 22:20:52) [MSC v.1916 32 bit (I
When the process is started it should only run the skript like you type:
py yourPath/example.py in the windows shell. shell_exec() in my case feezes the current session and exec dont work. The Script works fine when i execute it via pycharm.
You may use Symfony Process https://symfony.com/doc/current/components/process.html
Installation
composer require symfony/process
Usage
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
$process = new Process(['py pathtoSkript/example.py']);
// or $process = new Process(['python', 'pathtoSkript/example.py']);
try {
$process->mustRun();
echo $process->getOutput();
} catch (ProcessFailedException $exception) {
echo $exception->getMessage();
}
Try this
$command = escapeshellcmd('py pathtoSkript/example.py');
$output = shell_exec($command);
$output;
ref link https://www.php.net/manual/en/function.escapeshellcmd.php

Command line parameters for an inline python script?

I have a set of comman-line tools that I implement as bash functions, eg:
function sf
{
sftp $(svr $1)
}
where svr is another function that translates a short name to a fully qualified domain name. I got the idea that I wanted to convert this function:
function irpt
{
~/tools/icinga_report $*
}
to something like:
function irpt
{
python <<!
import requests
...lots of python stuff...
!
}
This works perfectly, except for one thing: I need to add the parameters somewhere, but I can't see where. I have tried to enclose the whole python block in { }, but it doesn't work:
function irpt
{
python <<!
import requests
...lots of python stuff...
!
}
The shell doesn't accept the definition:
-bash: /etc/profile: line 152: syntax error near unexpected token `$*'
-bash: /etc/profile: line 152: `} $*'
Is there any way to implement this?
===EDIT===
Inspired by the answer I accepted, this is what I did, maybe it is useful for others:
function irpt
{
python <<!
import requests
param="$*".split(' ')
...lots of python stuff...
!
}
This works beautifully.
One way:
function irpt
{
python <<!
import requests
v1='$1'
print(v1)
!
}
Running the function:
$ irpt hello
hello
$
It looks a little weird, but you can use the bash <(command) syntax to provide a script file dynamically (in reality, a named pipe); the rest follows.
function demo {
python <(echo 'import sys; print(sys.argv)') "$#"
}
You can use something like this
foo() {
cmd=$(cat <<EOF
print("$1")
EOF
)
python -c "$cmd"
}
Alternatively,
foo() {
python -c $(cat <<EOF
print("$1")
EOF
)
}
And then use the function like
foo test

Categories

Resources