Execute Python script using Laravel? - python-3.x

I'm trying to execute a python script in a Laravel 5.8 project but I'm having problems with the Symfony/process class.
Basically, I want to run this python script that takes an excel form from the storage folder.
My first try was this
$process = new Process('C:\Python\python.exe C:\Users\"my path"\laravel\storage\app\images\cargaExcel.py');
$process->run();
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
echo $process->getOutput();
And the error is
Fatal Python error: _Py_HashRandomization_Init: failed to get random numbers to initialize Python
I also tried with shell_exec(), and if the two files (the excel and the python script are in the public path - app/public) it works.
I think the problem is that python only executes on the app/public folder, so I don't know how to run this in another path.
Python output is telling me that:
Working directory: C:\Users\"my path"\laravel\public
Does anyone know how to run this?

You can pass the working directory as the second argument of the process class
So it can be:
$process = new Process('C:\Python\python.exe C:\Users\"my path"\laravel\storage\app\images\cargaExcel.py', "/my/working/path/");
Also you may pass command as array
$process = new Process(['C:\Python\python.exe', 'C:\Users\"my path"\laravel\storage\app\images\cargaExcel.py'], "/my/working/path/");

Related

Trying to run a command in bash terminal using python script

I'm trying to create a python script for the Automation of downloading python in a specific folder for a reason.
The only part of my code that for some reason doesn't work is
import os
path_python = os.path.expanduser("~/Desktop/file/Python-3.6.8")
_ = os.system("export PATH=" + path_python +":$PATH")
_ = os.system("export LD_LIBRARY_PATH=" + path_python + "/lib" + ":$LD_LIBRARY_PATH")
_ = os.system("which python")
if I type in bash terminal
export PATH=/home/user/Desktop/file/Python-3.6.8:$PATH
export LD_LIBRARY_PATH=/home/user/Desktop/file/Python-3.6.8/lib:$LD_LIBRARY_PATH
and check with which python it works fine but I want to use these commands from within python itself.
I want to be able to run this script on any computer so I can't specify the path unless there is a way to specify a general path to the desktop without using the user.

How to invoke a java program with classpath from Python 3.x

I am trying to execute an external java program from a python 3.7 program using the java command with classpath. I am using subprocess.Popen module in Python. Somehow I am not able to get it working! Appreciate any assistance!
cmd = ['java',
'-classpath', 'C:/Users/Documents/MqTransfer.jar', 'C:/Users/Documents/com.ibm.mq.commonservices.jar',
'C:/Users/Documents/com.ibm.mq.headers.jar', 'C:/Users/Documents/com.ibm.mq.jar',
'C:/Users/Documents/com.ibm.mq.jmqi.jar', 'C:/Users/Documents/com.ibm.mq.pcf.jar',
'C:/Users/Documents/connector.jar', 'C:/Users/Documents/xerces.jar',
'MyMqTransfer', 'C:/Users/Documents/queueTransfer.properties']
jproc = subprocess.Popen(cmd, stdout=PIPE, stderr=PIPE)
output, errors = jproc.communicate()
print(output, errors)
I am getting the below error
b'' b'Error: Could not find or load main class C:.Users.Documents.com.ibm.mq.commonservices.jar\r\n'
When I try to run the java program from my batch script it runs fine! This is the command I use in my batch script. The issue is with my python code!
java -classpath MqTransfer.jar;com.ibm.mq.commonservices.jar;com.ibm.mq.headers.jar;com.ibm.mq.jar;com.ibm.mq.jmqi.jar;com.ibm.mq.pcf.jar;connector.jar;xerces.jar com.ibm.my.mq.MyMqTransfer C:\Users\Documents\queueTransfer.properties
Based on the error, I believe the process being executed is something like 'java -classpath C:/Users/Documents/MqTransfer.jar c:/Users/Documents/com.ibm.mq.commonServices.jar [followed by the rest of the arguments you are passing to process]' such that java is passed MqTransfer.jar as the entire classpath argument and thinks 'C:.Users.Documents.com.ibm.mq.commonservices.jar' is your class to launch. Try combining your entire intended classpath into the 3rd argument of your launch and I think you will be good. It would look something like this:
cmd = ['java',
'-classpath', 'C:/Users/Documents/MqTransfer.jar;C:/Users/Documents/com.ibm.mq.commonservices.jar;C:/Users/Documents/com.ibm.mq.headers.jar;C:/Users/Documents/com.ibm.mq.jar;C:/Users/Documents/com.ibm.mq.jmqi.jar;C:/Users/Documents/com.ibm.mq.pcf.jar;C:/Users/Documents/connector.jar;C:/Users/Documents/xerces.jar',
'MyMqTransfer', 'C:/Users/Documents/queueTransfer.properties']

python subprocess call from wsgi

When I run the exact same function from the python3 interpreter vs, apache via mod wsgi, they both run error free but one returns the command text from apache the stout is simply always blank. Again I am running the exact same function.
Backgorund, I want to run svn update on some code to do so I am using subprocess to simply call "svn update /path/to/repo"
def update():
p1=subprocess.Popen(["svn", "update", "/var/www/myrepocode"],stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
(ret, stderr) = p1.communicate(timeout=10)
return (str(ret.decode('utf-8')))
when i run from the python3 shell or another python 3 script called from the shell
from test import update
print(update())
it works fine and i get
"Updating '/var/www/myrepocode':\nAt revision 27.\n"
when I have a wsgi script and execute it from accessing the web page
def application(environ, start_response):
...
output = output + "---"+update() +"---"
...
response_headers = [('Content-type', 'text/html'), ('Content-Length',
str(len(output)))]
start_response(status, response_headers)
return [output.encode('utf-8')]
I get an empty string:
------
I do not have a python virtual environment, just normal python3 and there are no errors thrown either. I suspect this has to do with the user running it but I really don't know. setting shell=True doesn't change anything either. Any help is greatly appreciated.
Your update method does not return nor print stderr . Maybe you should check for errors first by adding the following line in the update method.
print(stderr)
If errors are produced, can you post them?

MATLAB MCC "??? Error Using ==> mcc, return status = 1"

I'm trying to compile a matlab .m file on a linux cluster using mcc. R2008b is installed on the cluster.
I am using http://www.it.northwestern.edu/research/sscc/matlabcompiler.html as a guide.
My plusone.m file is as follows:
function y = plusone(x)
if(ischar(x)), x = str2num(x), end;
y = x + 1;
I am running matlab on the cluster using the command "matlab -nodisplay".
I have run mbuild -setup and have added (my matlab root folder)/bin and /sbin to $PATH.
I am using the command mcc -m -v plusone.m from within MATLAB, and the full output is:
"??? Error using ==> mcc Error executing mcc, return status = 1."
This output is the same for a few different .m files and a number of different flag settings.
Without more error information, I'm a bit stumped. Suggestions about what might be causing the error or ways of getting more information about the error would be greatly appreciated.

How do you get the path of the running script in groovy?

I'm writing a groovy script that I want to be controlled via a properties file stored in the same folder. However, I want to be able to call this script from anywhere. When I run the script it always looks for the properties file based on where it is run from, not where the script is.
How can I access the path of the script file from within the script?
You are correct that new File(".").getCanonicalPath() does not work. That returns the working directory.
To get the script directory
scriptDir = new File(getClass().protectionDomain.codeSource.location.path).parent
To get the script file path
scriptFile = getClass().protectionDomain.codeSource.location.path
As of Groovy 2.3.0 the #SourceURI annotation can be used to populate a variable with the URI of the script's location. This URI can then be used to get the path to the script:
import groovy.transform.SourceURI
import java.nio.file.Path
import java.nio.file.Paths
#SourceURI
URI sourceUri
Path scriptLocation = Paths.get(sourceUri)
Note that this will only work if the URI is a file: URI (or another URI scheme type with an installed FileSystemProvider), otherwise a FileSystemNotFoundException will be thrown by the Paths.get(URI) call. In particular, certain Groovy runtimes such as groovyshell and nextflow return a data: URI, which will not typically match an installed FileSystemProvider.
This makes sense if you are running the Groovy code as a script, otherwise the whole idea gets a little confusing, IMO. The workaround is here: https://issues.apache.org/jira/browse/GROOVY-1642
Basically this involves changing startGroovy.sh to pass in the location of the Groovy script as an environment variable.
As long as this information is not provided directly by Groovy, it's possible to modify the groovy.(sh|bat) starter script to make this property available as system property:
For unix boxes just change $GROOVY_HOME/bin/groovy (the sh script) to do
export JAVA_OPTS="$JAVA_OPTS -Dscript.name=$0"
before calling startGroovy
For Windows:
In startGroovy.bat add the following 2 lines right after the line with
the :init label (just before the parameter slurping starts):
#rem get name of script to launch with full path
set GROOVY_SCRIPT_NAME=%~f1
A bit further down in the batch file after the line that says "set
JAVA_OPTS=%JAVA_OPTS% -Dgroovy.starter.conf="%STARTER_CONF%" add the
line
set JAVA_OPTS=%JAVA_OPTS% -Dscript.name="%GROOVY_SCRIPT_NAME%"
For gradle user
I have same issue when I'm starting to work with gradle. I want to compile my thrift by remote thrift compiler (custom by my company).
Below is how I solved my issue:
task compileThrift {
doLast {
def projectLocation = projectDir.getAbsolutePath(); // HERE is what you've been looking for.
ssh.run {
session(remotes.compilerServer) {
// Delete existing thrift file.
cleanGeneratedFiles()
new File("$projectLocation/thrift/").eachFile() { f ->
def fileName=f.getName()
if(f.absolutePath.endsWith(".thrift")){
put from: f, into: "$compilerLocation/$fileName"
}
}
execute "mkdir -p $compilerLocation/gen-java"
def compileResult = execute "bash $compilerLocation/genjar $serviceName", logging: 'stdout', pty: true
assert compileResult.contains('SUCCESSFUL')
get from: "$compilerLocation/$serviceName" + '.jar', into: "$projectLocation/libs/"
}
}
}
}
One more solution. It works perfect even you run the script using GrovyConsole
File getScriptFile(){
new File(this.class.classLoader.getResourceLoader().loadGroovySource(this.class.name).toURI())
}
println getScriptFile()
workaround: for us it was running in an ANT environment and storing some location parent (knowing the subpath) in the Java environment properties (System.setProperty( "dirAncestor", "/foo" )) we could access the dir ancestor via Groovy's properties.get('dirAncestor').
maybe this will help for some scenarios mentioned here.

Resources