I have built a website with a fairly complex structure and lots of javascript and php functions. I avoided jquery to make it lighter.
I now want to add a python function that should return a value to it. Most people recommend Flask for this, but all the examples I have found seem to require re-arranging the index page etc, which I don’t want to do (but please correct me if I am misunderstanding that).
So, the simple solution I thought about is to use ajax to call a php script, which in turn executes a python file. The problem, is that ajax isn’t waiting for the python script to complete and return the result.
I am mostly self-taught, so maybe what I did is all wrong, and any suggestion for a simple fix is much appreciated. Again, I’d like to avoid jquery and any major re-arrangement of pages etc.
Here is my code.
The ajax function that I use for lots of things on the site:
var ajaxResponseText = "";//a global variable that I use to get back the results of PHP functions
function ajaxRequestReturn(phpRequest, vars, isAsync=false, setHeader=false, jsonParsed=true){
ajaxResponseText = "";
var req = new XMLHttpRequest();
req.open("POST", phpRequest, isAsync);//not asynchronous
if(setHeader){
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
req.onProgress = function(){
console.log("READYSTATE: ", req.readyState );
}
req.onload = function(){
if(this.status==200){
console.log("READYSTATE: ", this.readyState);
console.log("responseText: ", this.responseText);
if(jsonParsed){
ajaxResponseText = JSON.parse(this.responseText);
}else{
ajaxResponseText = this.responseText;//php functions will echo a json array
}
// console.log(ajaxResponseText);
}else if(this.status==404){
ajaxResponseText = "Not found";
}
}
req.onerror = function(){
throw new Error("Bad request.");//this will stop the script and report the error
}
req.send(vars);
}
An event handler on the page calls:
ajaxRequestReturn("myPhpPythonCaller.php", vars="", isAsync=false, setHeader=false, jsonParsed=false)
myPhpPythonCaller.php simply has:
echo exec("pathToMyPythonEnv .venv/bin/python3 pathToMyPythonScript.py");
And the python script would produce and then print the result, say
from library import functionx
res = functionx()
print(res)
This set-up works for simple functions (e.g. print("hello") from MyPythonScript.py sends "hello" to ajaxResponseText, as expected ). However, if I call a function that takes time (I want to run an LLM, which would take dozens of seconds to produce an output), ajax doesn’t wait for the result, gets to status==200 and console.logs an empty ajaxResponseText.
What is the simplest, lightest way to do what I am trying to do?
Thank you so much for any tips!
2
Answers
Thanks to @MatthewFlaschen and @Olivier for their tips. I tried to run the php file directly, and that showed a bunch of errors, which the ajax set up wouldn't show. As Olivier suggested, the python script wasn't working. This was due to inconsistencies with file paths created when the file was called from the php directory. Lesson learned: always make sure each step works before adding more layers. Thanks!
If your Python LLM script works properly when you run it directly from the command line, it’s likely a timeout.
Call set_time_limit at the beginning of your PHP script to increase the limit.
EDIT: There may be an error being printed to standard error, which exec reportedly discards.
Start the process with proc_open, as described in this answer. Use that to access standard error. Read the answer’s comments too, especially about proc_close.