I'm creating an online python compiler using Django.
I have this code for executing the code
def stream_response():
try:
process = subprocess.Popen(['python', temp_code_file_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin = subprocess.PIPE)
process.stdin.write(b'Hello')
for line in iter(process.stdout.readline, b''):
yield f"data: {line.decode('utf-8')}\n\n"
for line in iter(process.stdin.readline, b''):
yield f"data: {line.decode('utf-8')}\n\n"
for line in iter(process.stderr.readline, b''):
yield f"data: {line.decode('utf-8')}\n\n"
finally:
os.unlink(temp_code_file_path)
The streaming process works fine, however, if the file contains an input statement e.g.
print("Hello")
name = input("Enter your name: ")
print(name)
The "Enter your name: " is not being streamed. How can I make it in a way that it'll be sent to my client, a specific javascript will run and append an input to the DOM, get the user input, and communicate it to the subprocess STDIN?
I have tried these questions:
python-communicate-with-subprocess-using-stdin
a-non-blocking-read-on-a-subprocess-pipe-in-python
how-do-i-write-to-a-python-subprocess-stdin)
But cant find a solution that will work in my use case
Make sure to close stdin. You could use communicate()
to send data to stdin, which closes stdin automatically.
main.py:
import subprocess, sys, os
temp_code_file_path = "/tmp/foo.py"
interpreter = os.path.abspath(sys.executable)
name_value = "Foobar"
process = subprocess.Popen(
[interpreter, temp_code_file_path],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin = subprocess.PIPE
)
process.stdin.write(f"{name_value}\n".encode())
out, err = process.communicate()
process.wait()
#Everything from above just in one line:
#out, err = process.communicate(f"{name_value}\n".encode())
if process.returncode == 0:
print("Subprocess successfully executed!")
print(out.decode())
else:
print("ERROR, running subprocess:")
print(err.decode())
foo.py:
print("Hello")
name = input("Enter your name: ")
print(f"Your name is: {name}")
Out:
Subprocess successfully executed!
Hello
Enter your name: Your name is: Foobar