Issue
I have a flask server (app1) in file1:
from flask import Flask
app1 = Flask(__name__)
@app1.route('/', methods=['POST']):
return "Hello!"
if __name__ == '__main__':
app1.run(port=8080, debug=True)
And another flask server (app2) in file2:
import os
from flask import Flask, request
import subprocess
from time import sleep
app2 = Flask(__name__)
@app2.route('/run-path', methods=['POST'])
def run_path():
command_str = request.json.get('command')
command = command_str.split()
path_to_add = command[1]
os.environ['PYTHONPATH'] += f":{path_to_add}" # Adding the file that's going to be ran
# to PYTHONPATH to prevent import errors
subprocess.run(
command,
env=os.enivron.copy(),
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
sleep(600)
if __name__ == '__main__':
app2.run(port=2222, debug=True)
When someone sends a request to app2 (port 2222), it should run a python command, which is sometimes a flask server. The problem is that anything goes wrong when trying to run this command using subprocess.run.
It seems like it works, but when I'm trying to send a request to app1 (The server which we tried to start with subprocess), there's no response. The server is essentially down and it seems like the command did nothing.
If I set stdout to subprocess.STDOUT
, I get this exception:
Traceback (most recent call last):
File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1758, in <module>
main()
File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1752, in main
globals = debugger.run(setup['file'], None, None, is_module)
File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1147, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/Applications/PyCharm CE.app/Contents/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "/Users/galshahar/Desktop/Projects/PychramProjects/cba/src/api.py", line 48, in <module>
app.run(port=8080, debug=True)
File "/Users/galshahar/anaconda3/lib/python3.7/site-packages/flask/app.py", line 943, in run
run_simple(host, port, self, **options)
File "/Users/galshahar/anaconda3/lib/python3.7/site-packages/werkzeug/serving.py", line 814, in run_simple
inner()
File "/Users/galshahar/anaconda3/lib/python3.7/site-packages/werkzeug/serving.py", line 774, in inner
fd=fd)
File "/Users/galshahar/anaconda3/lib/python3.7/site-packages/werkzeug/serving.py", line 660, in make_server
passthrough_errors, ssl_context, fd=fd)
File "/Users/galshahar/anaconda3/lib/python3.7/site-packages/werkzeug/serving.py", line 574, in __init__
socket.SOCK_STREAM)
File "/Users/galshahar/anaconda3/lib/python3.7/socket.py", line 463, in fromfd
nfd = dup(fd)
OSError: [Errno 9] Bad file descriptor
Is what I'm trying to do is possible? What am I missing? I'm kinda lost :(
Thanks.
Solution
OK, I can tell you how to work around it. If you look at the traceback, flask
calls a package called werkzeug
to do the work. werkzeug
puts a note in the environment when it has to create a socket, presumably so it can just reuse that socket in forks. In your case, the second process inherits that environment, so it thinks an fd
already exists and tries to reuse it, but the fd
does not exist in this process.
The ugly solution that should work is to add this in your second script before starting port 8080 (or 2226, based on the original traceback ;):
del os.environ["WERKZEUG_SERVER_FD"]
Answered By - Tim Roberts
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.