I want to emulate command line call of my script (TensorFlow neaural chatbot model) in Django view and get output from console to variable.
When i do manually in terminal of my server:
python3 var/www/engine/chatbot/udc_predict.py --model_dir=var/www/engine/chatbot/runs/1486057482/
the output is good and printed out.
So in my Django view i do:
import subprocess
answer = subprocess.check_output(['python3', 'var/www/engine/chatbot/udc_predict.py','--model_dir=var/www/engine/chatbot/runs/1486057482/'], shell=True, stderr=subprocess.STDOUT, timeout=None)
print('answer', answer)
And answer variable is printed as b'' in Apache error log.
I cannot figure out what's wrong in my call.
The answer is to use .communicate() and PIPE:
from subprocess import Popen, PIPE
proc = Popen(
"python3 var/www/engine/chatbot/udc_predict.py --model_dir=var/www/engine/chatbot/runs/1486057482/",
shell=True,
stdout=PIPE, stderr=PIPE
)
proc.wait()
res = proc.communicate()
if proc.returncode:
print(res[1])
print('result:', res[0])
answer = res[0]
Related
bash_fc = rf"mysql -u {source_user_name} -h {source_ipv4_addr} --password={source_db_password}"
When I use the following functions for the above command,
from subprocess import PIPE,run
def cons_r(cmd):
response = run(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True, shell=True)
return response.stdout
response = os.popen(bash_fc)
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql: Unknown OS character set 'cp857'.
mysql: Switching to the default character set 'utf8mb4'.
ERROR 1045 (28000): Access denied for user 'root'#'pc.mshome.net' (using password: YES)
I can't read the output, is there a method you know of so I can read it?
You can read errors from standard error
import subprocess as sp
ret = sp.run(['ls', '*.bad'], stderr=sp.PIPE,
stdout=sp.PIPE, shell=True, encoding="cp857")
if ret.returncode == 0:
print(ret.stdout)
else:
print(ret.stderr)
This change fixed the problem
from subprocess import PIPE, run, STDOUT
def cons_r(cmd):
response = run(cmd, stdout=PIPE, stderr=STDOUT, universal_newlines=True, shell=True)
return response.stdout
What I want to do is call mysqldump to make a backup of a database table.
I have assembled a list of command line arguments, where db and tbl are the database and table names, respectively, and cnf is a properly formatted mysql configuration file (containing host, user and password),
args = ["mysqldump","--defaults-extra-file="+cnf,db,tbl]
print " ".join(args)
The output of the print is,
mysqldump --defaults-extra-file=dbserver.cnf test mytable
When I copy/paste the above line into the (bash) shell, it works.
When I use subprocess.Popen, the command fails,
import subprocess as sp
...
proc = sp.Popen(args, shell=False, stdin=sp.PIPE, stdout=sp.PIPE)
stdout = proc.communicate()
retcode = proc.wait()
if retcode>0: print "error",retcode
But when I join the args together, and call subprocess.Popen with shell=True,
the command works as desired,
cmd = " ".join(args)
proc = sp.Popen(cmd, shell=True, stdin=sp.PIPE, stdout=sp.PIPE)
stdout = proc.communicate()
retcode = proc.wait()
if retcode>0: print "error",retcode
Further investigation reveals that the first command does not seem to use the user/password credentials from the config file, but the second variant does.
Responses to other questions about subprocess.Popen make it clear that one should avoid the shell=True, but the first approach above fails.
Can anyone identify what I am doing wrong above?
Trying to run some windows application in a specific user mode. After passing the command, it will ask for password. So passing the password using proc.communicate() but its not working, Please help
from subprocess import Popen, PIPE
import time
cmd = "runas /user:administrator notepad.exe"
proc = Popen(cmd, stdout=PIPE, stdin=PIPE, stderr=PIPE)
print proc.stdout.read()
proc.communicate('password')
Are you open to using Pexpect instead? If yes, you can use the following:
import pexpect
cmd = "runas /user:administrator notepad.exe"
child_process = pexpect.spawn(cmd)
child_process.expect('assword')
child_process.sendline(password)
This code is not working as expected:
cmd = subprocess.Popen(["curl"], stdout = subprocess.PIPE)
(out,err) = cmd.communicate()
print(out)
print(err)
out is an empty line and err is None, instead the output is printed into the console.
I was expecting the output to be stored into a out variable, I'm using Windows 7 and Python 2.7.
How to read the output into a variable?
Type curl on the command line and you'll get an error message because you didn't supply required parameters. You didn't get anything in out because curl wrote the error message to stderr. And you didn't get err because you didn't redirect that pipe in Popen. Try this instead:
cmd = subprocess.Popen(["curl"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out,err = cmd.communicate()
print('out:', out)
print('err:', err)
print('returncode:', cmd.returncode)
I know, I want always more!
I am wondering how I can do something like this in fabric:
def deploy():
local('git pull origin dev')
gitusername = "test"
gitpwd = "testpassword"
# here render credentials to stdin so that no need to type in in console
local('python manage.py collectstatic')
confirm_type = "yes"
# here render 'confirm_type' to stdin so that I dont have to type in console
local('python manage.py migrate')
local('/etc/init.d/nginx restart')
I thought of fabric.operations.prompt but I dont need prompt. I want that fabric reads the credentials from variables and goes on further without asking me anything..
any ideas?
As stated in fabric's documentation, use subprocess to send data via stdin (used code from "how do i write to a python subprocess' stdin"):
from subprocess import Popen, PIPE, STDOUT
p = Popen(['python', 'manage.py', 'collectstatic'], stdout=PIPE, stdin=PIPE, stderr=PIPE)
stdout_data = p.communicate(input='yes')[0]
Remove the stdout, stderr parameters if you want to see the output.
Also, in case of collectstatic you can just specify a --noinput parameter without playing with pipes.