简体   繁体   中英

Python: how to use Flask to operate STDIN and STDOUT of subprocess.Popen?

I have an program that operate with STDIN and STDOUT. I want to make a API for it. Just with one POST - string for input and string for output.

The thing is the program has to load some data to the RAM and after that it is ready for multiple STDIN-STDOUT operations.

It is easier to show my code instead of explaining what I am doing.

#!/usr/bin/python3
from flask import Flask
from flask import request
import os
import sys
import subprocess

app = Flask(__name__)
app.url_map.strict_slashes = False

@app.route('/api/v1/someroute/', methods=['POST'])
def do_it():
    request_str = request.get_data().decode('utf-8').strip()
    request_lines = request_str.split('\n')
    output_list=[]

    for line in request_lines:
        output=''
        proc.stdin.write(line.encode())
        proc.stdin.close()
        output = proc.stdout.read().decode()
        print("output: ")
        print(translation)
        print("DONE")
        output_list.append(output.strip())
    print("MY output_list: ")
    print("output_list)
    print("DONE")
    return '\n'.join(output_list), 200

if __name__ == '__main__':
    proc = subprocess.Popen(["somepath", "some args"], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
    app.run(host='0.0.0.0',port=int(sys.argv[1]))

Flask works fine, but when I send a POST request with curl I get:

Name:*pogram name*  VmPeak:3021296 kB   VmRSS:300828 kB RSSMax:2992548 kB   user:43.311 sys:1.116   CPU:44.426  real:56.341
MY output: 

DONE
MY output_list: 
['']
DONE

What do I miss?

Also, when I try to send second request Flask response with 500, because I try to write to closed stdin. But if I delete "proc.stdin.close()" program just freezes.

UPDATE, When I do it without Flask. etc. Simpliest way.

>>> import subprocess
>>> proc = subprocess.Popen(["some program", "some args"], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
>>> proc.stdin.write("hello world".encode())
>>> proc.stdin.close()
>>> print(proc.stdout.read().decode())

>>> 

I guess you have an error either in a programm you call from python or in arguments you pass, so the output of that call is empty.

First make sure the programm with args you pass to Popen actually outputs anything by calling the same from your command line.

Your simple snippet should work fine. Test it with cat for example:

import subprocess

proc = subprocess.Popen(['cat'], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
proc.stdin.write('hello world'.encode())
proc.stdin.close()
print(proc.stdout.read(), 'out')

Also you could use communicate() instead of write() + close() + read()

import subprocess

proc = subprocess.Popen(['cat'], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
out, err = proc.communicate(input='communicated input')
print(out)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM