I'm currently calling the main python file in larval function, and inside that main python file I'm calling another 2 files ( PowerShell and sub python file) the problem is when the Laravel function is triggered it only call the main python file, however when I call the main python file using terminal all the files are executed like below:
Laravel function:
public function initialize(Request $request)
{
$store_name = $request->get('store_name', 1);
if (empty($store_name)) {
return 'Missing store name';
} else {
$processes = File::get("/root/flask/android_api/processes.txt");
File::put('/root/flask/android_api/url.txt', $store_name );
$process = new Process(['python3.6', '/root/flask/android_api/buildAPK.py']);
$process->run();
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
} else {
return 'Starting the processes to build';
}
}
}
and within the main python file I have:
try:
p = subprocess.Popen(["/usr/bin/pwsh",
"/root/flask/android_api/set_apk_builder.ps1", '-ExecutionPolicy',
'Unrestricted',
'./buildxml.ps1'],
stdout=sys.stdout)
p.communicate()
except:
file = open ("/root/flask/android_api/log.txt", "w")
file.write ("fail")
file.close()
import slack
// call(["python", "/root/flask/flask.py"])
os.system('python3.7 /root/flask/flask.py')
Edit:
now I changed the build to be direct from laravel function to generate the apk
using this command:
public function initialize(Request $request)
{
$store_name = $request->get('store_name', 1);
if (empty($store_name)) {
return 'Missing store name';
} else {
return shell_exec('cd /var/www/html/androidProject && chmod +x gradlew && ./gradlew assembledemoDebug');
}
}
however, the command line returns the Gradle command build is starting but it doesn't create a folder and generate the apk
the Current folder structure /var/www/html and inside html is the project folder and laravel project
note: before I call Gradle build command inside Laravel function, I used to call python file and that python file is calling Gradle command but I had the same issue the apk is not created, but when I run the same python file from bash command it works fine
There are 2 ways you can accomplish this:
The first is to include your commands into a .sh file that you should make it executable using this command:
chmod +x file.sh
Then you should call that file from laravel using Symfony process so you can get details of the log process and errors:
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
$process = new Process('sh /folder_name/file_name.sh');
$process->run();
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
echo $process->getOutput();
Then include all commands in that file you wish to run.
Second you can run those commands using
$output = shell_exec('ls -lart');
then echo "<pre>$output</pre>";
You'll need to move all your writable files into public directory in Laravel, because that's where everything should be editable.'=
I actually suggest the first one as you don't need to change owner of some folders to www-data to give write permissions.
Related
I'm facing quite simple problem, yet still not able to figure out what in particular causes that, and - more importantly - how to solve it.
I'm currently on Linux, and I would like to run an python app (script) from a Java application. The script is on PATH, thus I really would like to utilise that (avoid using absolute path to the script), if possible.
However, all I tried resulted in various forms of "File does not exist".
Sample
As a demonstration, I've tried to run one python3-based app (meld)
and one binary-built app (ls) for comparison:
$ which ls
/usr/bin/ls
$ file /usr/bin/ls
/usr/bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=[...], for GNU/Linux 3.2.0, stripped
$ which meld
/usr/bin/meld
$ file /usr/bin/meld
/usr/bin/meld: Python script, UTF-8 Unicode text executable
$ head -n1 /usr/bin/meld
#!/usr/bin/python3
Nextly, I've created simple Java main, which tries several ways how to start theese:
package cz.martlin.processes;
import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.util.List;
import java.util.stream.Collectors;
public class ProcessPlaying {
public static void main(String[] args) {
List<List<String>> commands = List.of(
List.of("ls"),
List.of("/usr/bin/ls"),
List.of("meld"),
List.of("/usr/bin/meld"),
List.of("python3", "/usr/bin/meld"),
List.of("/usr/bin/python3", "/usr/bin/meld"),
List.of("sh", "-c", "meld"),
List.of("sh", "-c", "/usr/bin/meld"),
List.of("sh", "-c", "python3 /usr/bin/meld")
);
for (List<String> command : commands) {
run(command);
}
}
private static void run(List<String> command) {
System.out.println("Running: " + command);
//String executable = command.get(0);
//boolean exists = new File(executable).exists();
//System.out.println("Exists the " + executable + " ? " + exists);
try {
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectError(Redirect.INHERIT);
Process proc = pb.start();
// Process proc = Runtime.getRuntime().exec(command.stream().collect(Collectors.joining(" ")));
int code = proc.waitFor();
System.out.println("OK, return code: " + code);
} catch (IOException e) {
System.out.println("Failed to start: " + e.toString());
} catch (InterruptedException e) {
System.out.println("Failed to await: " + e.toString());
}
System.out.println();
}
}
Here are the results:
Running: [ls]
OK, return code: 0
Running: [/usr/bin/ls]
OK, return code: 0
Running: [meld]
Failed to start: java.io.IOException: Cannot run program "meld": error=2, Directory or file doesn't exist
Running: [/usr/bin/meld]
Failed to start: java.io.IOException: Cannot run program "/usr/bin/meld": error=2, Directory or file doesn't exist
Running: [python3, /usr/bin/meld]
python3: can't open file '/usr/bin/meld': [Errno 2] No such file or directory
OK, return code: 2
Running: [/usr/bin/python3, /usr/bin/meld]
/usr/bin/python3: can't open file '/usr/bin/meld': [Errno 2] No such file or directory
OK, return code: 2
Running: [sh, -c, meld]
sh: line 1: meld: command not found
OK, return code: 127
Running: [sh, -c, /usr/bin/meld]
sh: line 1: /usr/bin/meld: Directory or file doesn't exist
OK, return code: 127
Running: [sh, -c, python3 /usr/bin/meld]
python3: can't open file '/usr/bin/meld': [Errno 2] No such file or directory
OK, return code: 2
To sum it up:
all of the commands tried works when executed directly from the shell (either sh or bash)
executing the binary works either by the full path (/usr/bin/ls) or by just the name (ls)
executing the python script the same way doesn't work neither way
when trying to run the python3 interpreter and populate the script path as an argument to the python, now the python yields the script file doesn't exist
trying to populate it as a command to the brand new shell didn't help either
I've tried to use the Runtime#exec (based on this comment: https://stackoverflow.com/a/36783743/3797793) to start the process (both the exec(String) and exec(String[] forms), but no sucess (none of the listed commands did actually execute).
Thus, my question is/are:
What do I understand wrong?
How to start the Python script from Java?
Would some small (ba)sh script wrapper do the job?
Since it's python3-based, Jython wouldn't help here (because the latest one is 2.7.*), would it?
Further requirements:
As mentioned, I would like to be able to avoid using full path to the Python script
Also, I would like to have platform independant solution (at least Linux and Windows compatible)
Thanks in advance
I've created a DotNet Core Razor MVC project and in there, I have created a directory called python. Within that python directory, I have created a python script called myscript.py.
Following the real-time chat example for SignalR, I have added a function to my ChatHub which is supposed to execute myscript.py:
private string ProcessMessage(string message)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = "/Users/SomeUser/Documents/Code/VisualStudio/MyProject/MyProject/python/myscript.py";
start.Arguments = message;
start.UseShellExecute = false;// Do not use OS shell
start.CreateNoWindow = true; // We don't need new window
start.RedirectStandardOutput = true;// Any output, generated by application will be redirected back
start.RedirectStandardError = true; // Any error in standard output will be redirected back (for example exceptions)
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string stderr = process.StandardError.ReadToEnd(); // Here are the exceptions from our Python script
string result = reader.ReadToEnd(); // Here is the result of StdOut(for example: print "test")
return result;
}
}
}
Notice I have provided the full path to start.FileName. However, when I run this, I get a permission denied error.
I've tried various combinations of that path (e.g. ~/python/myscript.py)
How can I resolve this? I'm running VS for Mac, if that makes a difference.
I wanna run in C# console app python script with libraries like numpy, pandas, matplotlib.pyplot. If I run simple print('hello world') and save it as test.py it works.
I added to PATH : D:\ProgramData\Anaconda3\Library\bin but it didn't help me too. Thanks for try helping me!
Code:
// full path to .py file
string pyScriptPath = #"C:\Users\micha\Documents\ML\multipleLinearRegression\multiple_linear_regression.py";
string outputString = null;
// create new process start info
ProcessStartInfo prcStartInfo = new ProcessStartInfo
{
// full path of the Python interpreter 'python.exe'
FileName = #"D:\ProgramData\Anaconda3\python.exe", // string.Format(#"""{0}""", "python.exe"),
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = false,
Arguments = #"C:\Users\micha\Documents\ML\multipleLinearRegression\multiple_linear_regression.py"
};
// start process
using (Process process = Process.Start(prcStartInfo))
{
// read standard output JSON string
using (StreamReader myStreamReader = process.StandardOutput)
{
outputString = myStreamReader.ReadLine();
process.WaitForExit();
}
}
Console.WriteLine(outputString);
console error
You said it works when you run the script with Python. Are you first creating an environment before running it? That may be the issue why it doesn't work when running it from C#.
So I'm trying to run a simple python file called test.py through the Node JS child process, however it keeps saying that python3: can't open file './test': [Errno 2] No such file or directory. I tried everything to fix this error. For example, the python script ran successfully from the same directory the typescript file is present, I even tried the full path, the relative path for the python file and it still didn't work. I kindly request someone too look into this, thank you!
test.py
import sys
print("hello world")
sys.stdout.flush()
var spawn = require("child_process").spawn;
var child = await spawn("python3", ['./test.py']);
let dataMain = "";
child.stdout.on("data", (data: Buffer) => {
// Do something with the data returned from python script
console.log(data); // buffer data
dataMain += data.toString();
});
child.stdout.on("end", () => {
console.log("end");
console.log(dataMain);
});
child.stderr.pipe(process.stderr); // prints out the error
Worked with ${process.cwd()}/test.py
I'm running python in a node web app, and I'm trying to load and read a file in python, do something with it, then spit it out to node.js.
When I run the following python code, nothing happens.
Python
import json
import sys
with open('trainingData.json') as file:
data = json.load(file)
print(data)
print('hello from python')
sys.stdout.flush()
When I remove with open, then it works well. How can I read a file in python and call that file in node.js? Here's the node code
Node
app.get('/', (req, res) => {
const spawn = require('child_process').spawn;
const process = spawn('python', ['./python/script.py', 'Hello', 'World']);
process.stdout.on('data', data => console.log(data.toString()));
res.send('he');
});
(When I run the python file fro the terminal, it works correctly.)
You can use spawn's cwd (current working directory) option, to specify the directory. To set it to the "current" current working directory use __dirname.
const process = spawn('python', ['./python/script.py', 'Hello', 'World'], {cwd: __dirname});