I have a Centos 7 server with cPanel and I'm working on a Telegram bot for my business needs. The bot should be able to run a terminal command with os.system or subprocess.Popen, however both options do not work when configured through a webhook + wsgi process.
I tested both with bot.polling method and they worked as a charm, however after I switched to webhook method served by flask and wsgi, both stopped working for me. I have tried the following:
mycommand = "python3.6 GoReport.py --id 31-33 --format word"
os.chdir('dir_to_run_command_from')
os.system(mycommand)
and the following one:
mycommand = "python3.6 GoReport.py --id 31-33 --format word"
subprocess.Popen(mycommand, cwd="dir_to_run_command_from", shell=True)
Both options simply do nothing right now. I tried to print them both and received 0 as a response. I wonder if the issue is caused by permissions or something.
I expect both options to work through webhook + wsgi as good as they work through bot.polling method.
I think I got it wrong. Your script writes a report to a specific directory. You do not need a result in your application route.
I wrote a small test application called tryout. It runs in a virtual environment.
$ mkdir tryout
$ cd tryout
$ python3 -m venv tryout
$ source tryout/bin/activate
$ export FLASK_APP=tryout/app
$ export FLASK_ENV=development
$ flask run
Directory structure:
/tryout
/app/*
/bin/*
/include/*
/lib/*
/subdir/*
Application:
# /tryout/app/__init__.py
import sys, os
from flask import Flask
def create_app(env=os.getenv('FLASK_ENV', 'development')):
app = Flask(__name__)
@app.route('/run-script')
def run_script():
import subprocess
cmd = 'python script.py'
cwd = 'subdir'
ret = subprocess.check_output(cmd, cwd=cwd, shell=True)
print(ret)
return ret, 200
return app
app = create_app()
Script:
# /subdir/script.py
import os, sys
def main():
with open('report.txt', 'w+') as fp:
fp.write('Info\n')
sys.stdout.write('It works!')
if __name__ == '__main__':
main()
It works!
A new file named "report.log" is written into the "subdir"-directory.
In Browser appears "It works!".
Hope I could help you or I have no real idea of what you want to do.
If you want to run an external script from inside flask, you could use subprocess to run the script from the command line. This is the right solution.
@app.route('/run-script')
def run_script():
cmd = '<your command here!>'
result = subprocess.check_output(cmd, cwd='<your wordir>', shell=True)
return render_template('results.html', **locals())
Have fun!
@Bogdan Kozlowskyi
Is it possible to pipe on the command line? Do you need to return a result to the user?
cmd = 'first_cmd | tee report.log'
result = subprocess.check_output(cmd, cwd='<your wordir>', shell=True)
Perhaps you should look for shell commands like '>>', '>' and 'tee'.
Seems to be a user-groups permission problem (execute and write).