I am struggling with a weird issue. I have a Python script that is accessed from a page via PHP and returns a JSON object with about 20 variables. All of them work all of the time except one that always returns an empty value. Directly running the Python script on the server returns a value every time, but php never sees it. I have tried output as a string, as an int, and even a string combined with a preset value. The posted code has only two shown, most of the functional values are omitted for length. ("cpul" is the one not working.)
PythonScript.py:
#!/usr/bin/python2.7
import os, json
def getCPUtemperature():
res = os.popen('vcgencmd measure_temp').readline()
tmp = (1.8 * float(res.replace("temp=","").replace("'C\n",""))) + 32
return(tmp)
# Return % of CPU used by user as a character string
def getCPUuse():
val = str(os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip(\
)[2:4])
return(val)
result = {'cput': CPU_temp, 'cpul': CPU_usage}
print json.dumps(result)
OUTPUT FROM SSH TERMINAL: {"cpul": "9", "cput": 106.16000000000001}
phpScript.php just passes the result on to the browser:
<?php
session_start();
try {
$result = exec('/usr/bin/python /scripts/PyhtonScript.py');
echo $result;
} catch (Exception $e) {
echo '{"res" : "ERROR", "msg" : "Caught exception: ' . $e->getMessage() . '"}';
}
?>
OUTPUT FROM BROWSER: {"cpul": "", "cput": 106.16000000000001}
If I change PythonScript.py 'result' to say:
result = {'cput': CPU_temp, 'cpul': 'foo'}
OUTPUT FROM BROWSER: {"cpul": "foo", "cput": 106.16000000000001}
and if I change PythonScript.py 'result' to say:
result = {'cput': CPU_temp, 'cpul': 'foo' + CPU_usage}
OUTPUT FROM BROWSER: {"cpul": "foo", "cput": 106.16000000000001}
If I modify the function to output an int rather than a string I get the same results without the quotes:
OUTPUT FROM SSH TERMINAL: {"cpul": 9, "cput": 106.16000000000001}
OUTPUT FROM BROWSER: {"cpul": "", "cput": 106.16000000000001}
The value is a percentage, so I would love to multiply it by 100 before sending, but if I modify the function as:
def getCPUuse():
val = str(os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip(\
))
mod = int(val) * 100
return(mod)
OUTPUT FROM SSH TERMINAL: {"cpul": 90, "cput": 106.16000000000001}
OUTPUT FROM BROWSER: Nothing, blank screen
APACHE2/error.log:
Traceback (most recent call last):
File "/var/www/html/assets/scripts/info_lkp.py", line 49, in <module>
CPU_usage = getCPUuse()
File "/var/www/html/assets/scripts/info_lkp.py", line 29, in getCPUuse
mod2 = int(mod)*10
ValueError: invalid literal for int() with base 10: ''
'unknown': I need something more specific.
Any idea what I am missing before I run out of hair to pull out? As stated, posted code is truncated to remove unrelated working similar functions and their associated outputs.
This is a Python error
When you multiply it by 100 before sending it, in your python script, error happens there.
And value is being lost, well, not because of the PHP.
It's because your python script does not return valid JSON.
Read about this error here ValueError: invalid literal for int() with base 10: ''
Related
So i have two codes, one of them is just a simple code that i used to test out some php functions. I'm trying to print out the JSON string into my html, one of the codes is working but the other isn't.
So let's say that we have two sets of codes : first.php & first.py , second.php & second.py
first.php looks like this:
<?php
exec("C:/Users/hln/Anaconda3/envs/tensorflow1/python.exe C:/tensorflow1/models/research/object_detection/first.py", $output);
$someOutput = json_decode($output[0], true);
echo "<h3>" . $someOutput['rightCoordinate'] ."</h3>";
echo "<h3>" . $someOutput['leftCoordinate'] ."</h3>";?>
first.py looks like:
import json
a = 1 + 3
b = 5 + 5
x = {
"leftCoordinate": a,
"rightCoordinate": b
}
y = json.dumps(x)
print(y)
print()
second.php looks like this:
<?php
exec("C:/Users/hln/Anaconda3/envs/tensorflow1/python.exe C:/tensorflow1/models/research/object_detection/second.py C:/xampp/htdocs/w3layout/finalproject/uploads/10.PNG 10.PNG 2>&1",$output);
$someOutput = json_decode($output[0], true);
echo "<h3>" . $someOutput['theWidth'] ."</h3>"; ?>
second.py looks like:
outputvalues = {
"leftCoordinate" : x_min(each of these are already defined),
"rightCoordinate" : x_max,
"lowerCoordinate" : y_min,
"upperCoordinate" : y_max,
"numInjuries" : count,
"theWidth" : im_width,
"theHeight" : im_height
}
y = json.dumps(outputvalues)
print(y)
when i run them in command prompt, the first one will result:
{"leftCoordinate": 4, "rightCoordinate": 10}
and when i put it in my html it will print out 4 and 10
the second one have this result in command prompt:
{"leftCoordinate": 34.47790487855673, "rightCoordinate": 251.67991018295288, "lowerCoordinate": 208.6769086420536, "upperCoordinate": 388.4499931335449, "numInjuries": 1, "theWidth": 327, "theHeight": 503}
but it won't print out any result in html
is there anything that i should change?
This might not be a helpful answer because there does not seem to be anything wrong with your code.
I placed the following at the top of second.py:
import json
x_min = 34.47790487855673
x_max = 251.67991018295288
y_min = 208.6769086420536
y_max = 388.4499931335449
count = 1
im_width = 327
im_height = 503
and removed the absolute paths in second.php:
exec("second.py 10.PNG 10.PNG 2>&1",$output);
Now php second.php shows me <h3>327</h3>.
This is on Windows 10 with PHP 7.3.1 and Python 3.7.4.
Edit: Tried it on Ubuntu 19.04/PHP 7.2.19/Python 2.7.16 and got the same result.
Based on your comments the problem is the fact that the Python script generates a warning which is then passed to the PHP script.
One way to ignore the warnings is to add the -W option with a value ignore. The line in the PHP script would then look something like this:
exec("python -W ignore second.py", $output);
I need to pass a multi-word argument from PHP to Python.
Passing only a single word poses no problem, however, how do I add the additional parameter that will result in a successful solution?
I have tried several ways to pass the additional parameter without any success, it result in either a 500 Internal Server Error or no response from the python script. Using 2>&1 also do not return any error messages.
There are six instances where additional parameter are optional or required for a successful response.
I can send the single word argument:
$command = escapeshellcmd("python /home/nova_api.py 'getwithdrawalhistory' 2>&1");
This will return the proper response of:
{"items":[],"message":"Your trade history with recent first","page":1,"pages":0,"perpage":100,"status":"success","total_items":0}
My attempts to pass the additional parameter from PHP to Python:
$command = escapeshellcmd("python /home/nova_api.py 'getwithdrawalhistory, { \'page\': 1 }' 2>&1");
$command = escapeshellcmd("python /home/nova_api.py 'getwithdrawalhistory, { \'page\': \'1\' }' 2>&1");
$command = escapeshellcmd("python /home/nova_api.py 'getwithdrawalhistory, { \'page\': \"1\" }' 2>&1");
All three result in a blank page - no response and no error returned.
You're doing the right thing by escaping, but using escapeshellcmd isn't what you want. It has no concept of arguments, so isn't working the way you expect. PHP provides a method to quote and escape individual arguments to shell commands:
<?php
$cmd = "python";
$args = [
"/home/nova_api.py",
"getwithdrawalhistory, { 'page': 1 }",
];
// just a fancy way of avoiding a foreach loop
$escaped_args = implode(" ", array_map("escapeshellarg", $args));
$command = "$cmd $escaped_args 2>&1";
I am trying to write a php code that takes coefficients from a html form, sends them to a python algorithm that returns a json object. That object is a list of player names, basically {"Ji" : "Firstname Lastname"} for i from 1 to 15.
The python code (interface.py) I have to create this json is :
import json
i=0
for joueur in best_team:
i+=1
output["J%s"%(i)]=joueur['nom']
out=json.dumps(output)
print(out)
best_team is a list of player dictionnaries with data on them. My player names don't involve any non ASCII characters or whatever.
My php code is the following :
$command = "python interface.py";
$command .= " $coeff1 $coeff2 $coeff3 $coeff4 $coeff5 $coeff6 $coeff7 $coeff8 $coeff9 $coeff10 2>&1";
$pid = popen( $command,"r");
while( !feof( $pid ) )
{
$data = fread($pid, 256);
$data= json_decode($data) ;
echo $data->J1;
flush();
ob_flush();
echo "<script>window.scrollTo(0,99999);</script>";
usleep(100000);
}
pclose($pid);
I call the coefficients from the html and then send back the results via a js file.
But I just get the following error : Notice: Trying to get property of non-object.
Nothing wrong with the js file because if I try instead :
$string = '{"foo": "bar", "cool": "attributlong"}';
$result = json_decode($string);
echo $result ->cool;
It works.
Also if I have instead in my python file :
out={"foo":"bar","word":"longerthaneightcharacters"}
out=json.dumps(out)
print(out)
It works as well (replacing J1 by word in php code of course).
And funny enough, if i have in python:
output={}
i=0
for joueur in best_team:
i+=1
output["J%s"%(i)]="short"
output["J%s"%(i)]=str(output["J%s"%(i)])
out=json.dumps(output)
print(out)
It works, and if I replace "short" by "longerthaneightcharacters" it doesn't work anymore.
So basically my question is, why is there a maximum number of characters in my output loop and how can I bypass it ? Thanks, I am very confused.
This question already has answers here:
Running a Python script from PHP
(10 answers)
Closed 7 years ago.
I have a python script that I would like to run from PHP. This is my PHP script:
$data = array('as', 'df', 'gh');
// Execute the python script with the JSON data
$result = shell_exec('python /path/to/myScript.py ' . escapeshellarg(json_encode($data)));
// Decode the result
$resultData = json_decode($result, true);
// This will contain: array('status' => 'Yes!')
var_dump($resultData);
And this is my Python script:
import sys, json
# Load the data that PHP sent us
try:
data = json.loads(sys.argv[1])
except:
print "ERROR"
sys.exit(1)
# Generate some data to send to PHP
result = {'status': 'Yes!'}
# Send it to stdout (to PHP)
print json.dumps(result)
I would like to be able to exchange data between PHP and Python, but the above error gives the output:
ERROR NULL
Where am I going wrong ?
:::::EDIT::::::
I ran this:
$data = array('as', 'df', 'gh');
// Execute the python script with the JSON data
$temp = json_encode($data);
$result= shell_exec('C:\Python27\python.exe test.py ' . "'" . $temp . "'");
echo $result;
I am getting No JSON object could be decoded
On my machine, the code works perfectly fine and displays:
array(1) {
'status' =>
string(4) "Yes!"
}
On the other hand, you may make a few changes to diagnose the issue on your machine.
Check the default version of Python. You can do this by running python from the terminal. If you see something like:
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
you're fine. If you see that you are running Python 3, this could be an issue, since your Python script is written for Python 2. So:
Python 3.4.0 (default, Apr 11 2014, 13:05:11)
[...]
should be a clue.
Again from the terminal, run python myScript.py "[\"as\",\"df\",\"gh\"]". What do you see?
{"status": "Yes!"}
is cool. A different response indicates that the issue is probably with your Python script.
Check permissions. How do you run your PHP script? Do you have access to /path/to/? What about /path/to/myScript.php?
Replace your PHP code by:
<?php
echo file_get_contents("/path/to/myScript.php");
?>
Do you get the actual contents?
Now let's add a few debugging helpers in your PHP code. Since I imagine that you are not using a debugger, the simplest way is to print debug statements. This is OK for 10-LOC scripts, but if you need to deal with larger applications, invest your time in learning how to use PHP debuggers and how do use logging.
Here's the result:
/path/to/demo.php
<?php
$data = array('as', 'df', 'gh');
$pythonScript = "/path/to/myScript.py";
$cmd = array("python", $pythonScript, escapeshellarg(json_encode($data)));
$cmdText = implode(' ', $cmd);
echo "Running command: " . $cmdText . "\n";
$result = shell_exec($cmdText);
echo "Got the following result:\n";
echo $result;
$resultData = json_decode($result, true);
echo "The result was transformed into:\n";
var_dump($resultData);
?>
/path/to/myScript.py
import sys, json
try:
data = json.loads(sys.argv[1])
print json.dumps({'status': 'Yes!'})
except Exception as e:
print str(e)
Now run the script:
cd /path/to
php -f demo.php
This is what I get:
Running command: python /path/to/myScript.py '["as","df","gh"]'
Got the following result:
{"status": "Yes!"}
The result was transformed into:
array(1) {
'status' =>
string(4) "Yes!"
}
yours should be different and contain a hint about what is happening.
I got it to work by adding quotes around the argument!
Like so:
<?php
$data = array('as', 'df', 'gh');
$temp = json_encode($data);
echo shell_exec('python myScript.py ' . "'" . $temp . "'");
?>
I'm trying to run a C program of adding two numbers with PHP in a web browser. But when I run the command
exec"gcc name.c -o a & a" it
returns some garbage result like sum is : 8000542.00. It doesn't ask for any input.
I want to give inputs to scanf from the browser. Please suggest to me how can I resolve my problem.
I have tried this but couldn't handle it successfully.
$desc = array(0=> array ('pipe','w'), 1=> array ('pipe','r'));
$cmd = "C:\xampp\htdocs\add.exe";
$pipes=array();
$p = proc_open($cmd,$desc,$pipes);
if(is_resource($p))
{
echo stream_get_contents($pipes[0]);
fclose($pipes[0]);
$return_value=proc_close($p);
echo $return_value;