Send command from PHP to running Python script - php

At the moment I am planning a project with the RaspberryPi.
Therefore I plan to write a script in Python that runs in the background and reacts to user input (buttons, rotary knob, etc.).
Additional to the Python script I have a webinterface with PHP under it. The goal is to lat the user change settings through the webinterface and pass the changed variables (e.g. a Twitter username) to the Python script so it can update its variables.
Unfortunatelly I have no idea how to pass data to the running Python script. Do you have any ideas?

store modifiable settigns in a json file
settings.json
{"twitter_user": "bob"}
before doing something load your json settings
myscript.py
import json
def do_something():
settings = json.load(open("settings.json"))
print settings["twitter_user"]
update your settings.json via php as needed
myscript.php
function change_twitter_user($uname){
$settings = json_decode(file_get_contents($file));
$settings["twitter_user"] = $uname
file_put_contents("/path/to/settings.json",json_encode($settings ));
}
thats probably the easiest way to do it
(although you do know that python has some very nice web stuff also right?)

Related

Pass data from php to python and get result

I want to send data from php to python and make some computations. After that I want to send result of that. The problem is I cannot send data from php to python.
python.php
username is working but shell_exec or python have problem
<?php
if(isset($_POST["username"])){
$nick = $_POST["username"];
echo shell_exec("python new.py '$nick'");
$jsonData = $_POST["prediction" ];
echo $jsonData;
}
?>
new.py
When I run python it prints C:\wamp\www\MLWebsite\website\new.py but it should be parameter
import pymysql.cursors
import sys
import urllib2, urllib
import requests
x=sys.argv[0]
print x
I want to get some idea about sending result because end of new.py
mydata=[('prediction','BIO')]
mydata=urllib.urlencode(mydata)
path='http://localhost/MLWebsite/website/python.php' #the url you want to POST to
req=urllib2.Request(path, mydata)
req.add_header("Content-type", "application/x-www-form-urlencoded")
page=urllib2.urlopen(req).read()
print page
I use Firebug plugin in Firefox and this error is also shown in webpage.
( ! ) Notice: Undefined
index: prediction in C:\wamp\www\MLWebsite\website\python.php on line
6 Call Stack #TimeMemoryFunctionLocation 10.0006245144{main}( )..\python.php:0
I assume the reason that you want to do it this way (i.e., using PhP to interact with user but having Python actually do the processing) is that you want to take advantage of python language for some tasks, but avoid having to use a separate webframework just for those tasks.
One way to accomplish it (albeit perhaps not the way you want to solve it) is to have PhP write the data to a text file with delimiters separating different chunks of data. Then have PhP call the Python file, which knows to read the text file.
In my example below Python writes to a file and PhP can open it if it wants, but you can go the other way as well. PhP could write to a .txt file, Python can read and manipulate, and then save to the same or different .txt file, and PhP can open and render the results.
Basically, you are using a .txt file as 'memory'.
This is an example:
<?php
echo "<h1>This is PhP!</h1>";
$returnedValue = shell_exec('/home/sitename/public_html/pythonFile.py');
echo $returnedValue; //This line may not be needed if there is nothing to return.
echo "<h2> Completed </h2>";
//Once the 'Complete' Above Renders in the Browser You Know that Python Did Whatever it Was Going to Do to the .txt File
//Now, if you want to have PhP Open the .txt File and Display it You Can
?>
#THIS IS PYTHON
#!/usr/bin/env python
file_object = open("NameOfTextFile.txt", "w+")
file_object.write("Hello World!")
file_object.close()
I realize this question is old, but I recently had the same issue and this is how I tried to resolve it. Hopefully it helps someone.
I think your question needs refinement.
From what I can tell, your python program is doing what one would expect.
$ cat 0.py
#!/usr/bin/python
import sys
print sys.argv[0]
print sys.argv[1]
$ chmod 755 0.py
$ python 0.py foo
0.py
foo
$ ./0.py foo bar
./0.py
foo
So, if your python program is prining 'new.py' as you wrote the question, I think that's expected behavior. Why you're passing unsanitized user input to a system call is another question. Why you're using a system call at all (why not set up a webservice with your python program?) is yet a further question.
I hope this helps.

How to execute python script with curl from php?

I want to execute python script with post data and get result from there using curl in php. If anyone have done this kind of functionality then please help. I have searched a lot but didn't get anything.
This is my python script path
cgi-bin/interactive.py
And i want to pass title=abc as post data.
I have done it with shell_exec in php file,
$command = escapeshellcmd('cgi-bin/interactive.py test');
$output = shell_exec($command);
echo $output;
But in this i am facing issue with sys.argv to fetch argument in python file.
Is it possible to pass argument with key=value with shell_exec? If yes then it can solve my problem otherwise i need to call with curl post data.
Thanks in advance!
To do advanced parsing of shell arguments you can use getopt or argparse modules. They are highly configurable and flexible.
Passing post data via shell arguments is, however, not proper as per the CGI spec (if this is supposed to be a true CGI application). Post data comes from stdin in CGI, so in your Python program you can read in the HTTP response like regular user input, and then parse out the POST data. See this thread for more info.

Pass form variables from PHP to Python (inside jumi in Joomla)

Is there a way for PHP to pass HTML form variables (POST) directly to a python script called with "passthru" in PHP without PHP having to know the variable names?
Can PHP pass the HTTP POST request to python so that i.e. the cgi module in python will read it like it was passed "from the web"?
Basic setup: Joomla CMS, with the jumi module.
NB! Python 2.4, PHP 5.3.3 on RedHat 5.9 - only standard packages.
One of the jumi applications is a python script which creates a form, and also handles the POST variables.
Reason: A lot more python knowledge in our shop, and the python script does a lot in the background.
In the jumi PHP script I have:
<?php
$var1 = $_REQUEST['myVar1'];
$var2 = $_REQUEST['myVar2'];
echo passthru('/usr/bin/python /var/www/html/joomla/jumi/portal-ldap.py '.$myVar1.' '.$myVar2);
?>
The python scripts then uses sys.arvg to process these variables.
It works - by all means, but it also means that any additinal variables must be known to both scripts.
Is there a way for PHP to pass the form variables directly to the python script in a way so that the "cgi" module in Python can process the variables as it would if I ran the python script with a framework/cgi/mod_python/...?
Python handling form variables:
import cgi
form = cgi.FieldStorage()
var1 = form.getvalue("myVar1", "nothing")
var2 = form.getvalue("myVar2", "nothing")
If you absolutely want to read the values through cgi.FieldStorage, you could run the python script on an HTTP server, preferably limiting its access to localhost. Executing the call over HTTP would also be a lot more secure than passing the parameters to passthrough() unparsed.
Alternatively, you could change your python script to use the getopt module, which makes it easier to define the argument in key-value pairs like this (paths omitted for brevity):
python portal-ldap.py --myvar1 nothing --myvar2 nothing
If you decide to keep using passthgough(), do remember to escape all the arguments with escapeshellarg().
Edit: You could also json_encode($_REQUEST) and pass it as a parameter, then json.loads() it in Python to get the array as a dictionary.
I'll answer my own question to explain how I used the info I've gotten.
I must also add that I'm limited by using python 2.4 and (maybe not limited by) simplejson - since I'm on RedHat 5.9 in this project - and want/need to keep to the supplied packages. So I have web --> Joomla --> jumi --> php --> python --> backend...
Building on the answer and comments from Kaivosukeltaja and supporting articles executing Python script in PHP and exchanging data between the two and http://pymotw.com/2/json/
In the jumi application / php-script I have put (amongst other things) the following to allow HTTP POST to be sent as a JSON object to my supporting python script.
echo passthru('/usr/bin/python /var/www/html/joomla/jumi/ldap-script.py '. escapeshellarg(json_encode($_POST)))
Then, in the python script I use sys.argv to read the variable, and simplejson to map the json object from PHP to a python dictionary (heavily simplified):
import sys
import simplejson as json
myjson = sys.argv[1]
mydict = json.loads(myjson)
I can now test if my desired keys can be found:
if ( 'var1' in mydict):
print mydict['var1']
The user posts to these variables in a simple form:
<form name="INPUT" action="" method="POST">
MyVar1 <input type="number" name="var1">
<input type=SUBMIT" value="Submit">
</form>
The avid reader will see that "var1" is referenced in most of these steps, while PHP isn't, don't have to be, aware of it.

Get windows title using php doesn't work on browser call

My problem is I need to fetch FOOBAR2000's title because that including information of playing file, so I create a execute file via Win32 API(GetWindowText(), EnumWindows()) and it's working good.
TCHAR SearchText[MAX_LOADSTRING] = _T("foobar2000");
BOOL CALLBACK WorkerProc(HWND hwnd, LPARAM lParam)
{
TCHAR buffer[MAX_TITLESTRING];
GetWindowText(hwnd, buffer, MAX_TITLESTRING);
if(_tcsstr(buffer, SearchText))
{
// find it output something
}
return TRUE;
}
EnumWindows(WorkerProc, NULL);
Output would look like "album artis title .... [foobar2000 v1.1.5]"
I created a php file like test.php, and use exec() to execute it.
exec("foobar.exe");
then in console(cmd) I use command to execute it
php test.php
It's working good too, same output like before.
Now I use browser(firefox) to call this php file(test.php), strange things happened.
The output only foobar2000 v1.1.5, others information gone ...
I think maybe is exec() problem? priority or some limitation, so I use C# to create a COM Object and register it, and rewrite php code
$mydll = new COM("FOOBAR_COMObject.FOOBAR_Class");
echo $mydll->GetFooBarTitle();
still same result, command line OK, but browser Fail.
My question is
Why have 2 different output between command line and browser. I can't figure it out.
How can I get correct output via browser.
or there is a easy way to fetch FOOBAR2000's title?
Does anyone have experience on this problem?
== 2012/11/28 edited ==
follow Enno's opinion, I modify http_control plug-in to add filename info, original json info is "track title".
modify as following
state.cpp line 380 add 1 line
+pb_helper1 = pfc::string_filename(pb_item_ptr->get_path());
pb_helper1x = xml_friendly_string(pb_helper1);
# 1: when firefox opens the php and it gets executed, it the context depends on the user which runs the php-container (apache), this is quite different from the commandline call which gets executed in your context
# 2 and 3: there seems to be more than one way for getting the title: use the foobar-sdk and create a module which simply reads the current title per api, then write your result in an static-html-document inside your http-root-folder OR use the http-client inside the sdk, with it, you do not need a wabserver, even better use a already implemented module: for instance foo_upnp or foo-httpcontrol
Good luck!
If your webserver runs as a service, in windows you need to enable "allow desktop interaction" for the service. Your php script runs as a child of the webserver process when requested via browser.

How do I include a PHP script in Python?

I have a PHP script (news-generator.php) which, when I include it, grabs a bunch of news items and prints them. Right now, I'm using Python for my website (CGI). When I was using PHP, I used something like this on the "News" page:
<?php
print("<h1>News and Updates</h1>");
include("news-generator.php");
print("</body>");
?>
(I cut down the example for simplicity.)
Is there a way I could make Python execute the script (news-generator.php) and return the output which would work cross-platform? That way, I could do this:
page_html = "<h1>News and Updates</h1>"
news_script_output = php("news-generator.php") //should return a string
print page_html + news_script_output
import subprocess
def php(script_path):
p = subprocess.Popen(['php', script_path], stdout=subprocess.PIPE)
result = p.communicate()[0]
return result
# YOUR CODE BELOW:
page_html = "<h1>News and Updates</h1>"
news_script_output = php("news-generator.php")
print page_html + news_script_output
PHP is a program. You can run any program with subprocess.
The hard part is simulating the whole CGI environment that PHP expects.
maybe off topic, but if you want to do this in a way where you can access the vars and such created by the php script (eg. array of news items), your best best will be to do the exec of the php script, but return a json encoded array of items from php as a string, then json decode them on the python side, and do your html generation and iteration there.
I think the best answer would be to have apache render both pages separately and then use javascript to load that page into a div. You have the slight slowdown of the ajax load but then you dont have to worry about it.
There is an open-source widget thing that will run multiple languages in 1 page but I cant remember what its called.
You could use urllib to get the page from the server (localhost) and execute it in the right environment for php. Not pretty, but it'll work. It may cause performance problems if you do it a lot.

Categories