Reputation: 13091
I have a running Flask app but want to pass any command via URL and make flask execute it on a host server and return results.
e.g. when running curl localhost:5000/run/"ls -l"
(command is ls -l
) -> expecting result:
.
..
file1
file2
etc..
So far I have:
import os
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello World!"
@app.route('/run/<command>')
def run(command):
return 'Run this %s!' % command
if __name__ == "__main__":
app.run(debug = True)
Thanks.
Upvotes: 0
Views: 14259
Reputation: 2320
I suggest to pass commands in a JSON request instead of sending them as URL parameters:
from subprocess import Popen, TimeoutExpired, PIPE
from flask import Flask, jsonify, abort, request
app = Flask(__name__)
@app.route("/", methods=["POST"])
def index():
req_json = request.get_json()
if req_json is None or "command" not in req_json:
abort(400, description="Please provide command in JSON request!")
proc = Popen(req_json["command"], stdout=PIPE, stderr=PIPE, shell=True)
try:
outs, errs = proc.communicate(timeout=1)
except TimeoutExpired:
proc.kill()
abort(500, description="The timeout is expired!")
if errs:
abort(500, description=errs.decode('utf-8'))
return jsonify(success=True, message=outs.decode('utf-8'))
@app.errorhandler(400)
def bad_request(error):
return jsonify(success=False, message=error.description), 400
@app.errorhandler(500)
def server_error(error):
return jsonify(success=False, message=error.description) , 500
Save it to, say server.py
, and run it:
$ FLASK_APP=server.py:app flask run
* Serving Flask app "server.py:app"
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Request example:
$ curl -X POST -H "Content-Type: application/json" -d '{"command": "ls -l"}' localhost:5000
{"message":"total 8\ndrwxr-xr-x 2 const const 4096 Jul 19 09:52 __pycache__\n-rw-rw-r-- 1 const const 1043 Jul 19 09:52 server.py\n","success":true}
Upvotes: 0
Reputation: 13091
Just made it to work:
import os
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello World!"
@app.route('/run/<command>')
def run(command):
out = os.popen(command).read()
return (out)
if __name__ == "__main__":
app.run(debug = True)
Upvotes: 3