Python json.load() doesn't work in PHP exec() - php

I have a python script that I wish to run from PHP using the exec() function. What the Python script does is it gets some data from a web API, stores the data in temporary files, then reads the files and puts some data in a csv file. The script runs fine when I test it alone. Now, I want to run it through exec(). When I first tried, I thought that the script wasn't running at all, but then I looked a bi further and realized that the script WAS in fact running, but stopped somewhere during the execution.
I then tried to redirect the output to a txt file with > output.txt to see where it went wrong. When I checked in the file and debugged a bit, I realized that the problem was the function json.load() in my Python script. The strange thing is that in the output.txt file, there is no error message displayed.
Here is what the output.txt file looks like.
And here is the python function that contains json.load().
def get_json_files_data(path, min = 1):
json_files = find_files(path, "json", min)
json_data = dict()
print("===========================================")
print("= Converting JSON data into Python object =")
print("===========================================")
for file in json_files:
base = os.path.basename(file) # name with extension (ex. 'file.json')
id = os.path.splitext(base)[0] # name without extension (ex. 'file') in this case, the names are the trip ids
opened_file = open(file)
print(10)
json_data[id] = json.load(opened_file) # get the json data as a python dict
print(11)
return json_data
I also tried to change the permission of the json files to 777, but that doesn't resolve the problem.
Does anyone have any idea? Let me know if any more code is needed.
Thanks a lot

I finally managed to make it work. Here's the solution if anyone is wondering.
The problem was the encoding. It was somehow different depending on how I was running the script. What I did was simply to specified the encoding with encoding='utf-8'. Here's what my code looks like now.
def get_json_files_data(path, min = 1):
json_files = find_files(path, "json", min)
json_data = dict()
print("===========================================")
print("= Converting JSON data into Python object =")
print("===========================================")
for file in json_files:
base = os.path.basename(file) # name with extension (ex. 'file.json')
id = os.path.splitext(base)[0] # name without extension (ex. 'file') in this case, the names are the trip ids
with open(file, 'r', encoding='utf-8') as opened_file:
json_data[id] = json.load(opened_file) # get the json data as a python dict
return json_data

Related

Send data from VBA (excel) to php and vice versa

Basically I want to communicate with a MYSQL server using php as the middle-ware.
I cannot connect directly to the database due to drivers needing to be installed and our IT will not allow drivers to be installed on our company computers.
I understand how to insert data using vba ->php->mysql but I cannot figure out how to get data from mysql to excel. vba->php->mysql->php->vba.
I want to do a query and send the results to vba excel.
Here is the VBA Code that works but it also sends multiple spaces back as well. Im not sure if this is the correct way to do this.
Private Sub ExtractPHP()
Dim item As String
Dim objHTTP As Object
Dim URL As String
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
URL = "http://localhost/php/requestdata.php"
objHTTP.Open "POST", URL, False
objHTTP.setRequestHeader "Content-type", "application/x-www-form-urlencode"
objHTTP.send ("")
Worksheets("hiddendata").Range("k4").Value = Replace(objHTTP.responseText, " ", "")
End Sub
The PHP code is as follows.
<?php
$con = mysqli_connect("localhost","root","","php") or die("Connection was not created!");
$select = "select name FROM users where id=5";
$run = mysqli_query($con,$select);
$value = mysqli_fetch_array($run);
$result = $value["name"];
echo $result;
?>
Result that is placed in the excel file has multiple spaces below the text. Is this the correct way to communicate between excel and mysql?
I am not sure about the VBA method and what exactly you need to do but one solution would be to write requestdata.php to parse the result of your query into a .csv file and then load that into Excel via VBA. Parsing the result array into the .csv plain text format is made even more trivial by the fact that PHP already has a function fputcsv($file, $records) to use (documentation).
i can help you 10% cause i programming in several languages but nothing vba/excell .I programming in php too...anyway my answer for you is :
Let say you create in C: a new folder and you create a runme.bat file there.
Using one methods to run a external .bat file and to grab external result from that runme.bat more or less like in
Execute a command in command prompt using excel VBA
Wait for shell command to complete
you can use like me a method to run from that batch php cli:
you can drop runme.php in that folder as well:
<?php
if(isset($argv[1])){
echo($argv[1]);
//here you can drop some mysql
}
?>
then you should understand how to reconfiger php ini to connect to mysql ,some problems you can dare are
PHP: mysql_connect() won't work via command line
if you put a command like this one i already check via windows cmd and works
c:\xampp\php>php "c:\test\runme.php" yep2
and you are getting "yep2"
as c:\test\ 's runme.bat version :
rem #echo off
set parameter=%1
set PHP_BIN="c:\xampp\php\php.exe"
set script=%cd%\runme.php
%PHP_BIN% %script% %parameter%
and for test we call it in cmd : runme yep2
with the result: yep2
then with the batch modiffied you can fill data in mysql let's say you will call that not runme.php but putmysqldata.php .
at this point creating another file php to read from mysql (even you use only one file php to write or read by calling it by different parameter) so you will be able to read from mysql
so isn't easy if you don't know much vba or how to do it.
following these steps i think if you know some vba more than me you can figure out the shortest way.

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.

Send command from PHP to running Python script

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?)

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