0

I'm writing a web application where users may attempt to solve various programming problems. The user uploads an executable .py file and the application feeds it some pre-determined input and checks whether the output is correct. (similar to how Codeforce works)

Assuming I have uploaded the user's script, how do I execute the user's script from within my own Python script, feeding the user's script input that would be captured by a normal input() function, and retrieving the output from print() functions so that I can verify its correctness?

1
  • What have you tried. Please make an effort to solve your problem before asking a question. More often then not, you'll end up solving your own problem. Commented Aug 29, 2016 at 3:34

1 Answer 1

1

Figured it out.

Note: If you are going to use this in a production environment, make sure you place restrictions on what the user can execute.

executor.py

import subprocess

# create process
process = subprocess.Popen(
        ['python3.4','script_to_execute.py'], # shell command
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
)

# encode string into bytes, since communicate function only accepts bytes
input_data = "Captured string".encode(encoding='UTF-8')

# send the input to the process, retrieve output of print() function
stdoutdata, stderrdata = process.communicate(input=input_data)

# decode output back into string
output_data = stdoutdata.decode(encoding='UTF-8')

print(output_data)

script_to_execute.py

input_data = input()

print("Input recieved!\nData: " + input_data)

Output of executor.py

Input recieved!
Data: Captured string
Sign up to request clarification or add additional context in comments.

4 Comments

If you execute any script that somebody upload, you can count the seconds until your server will do something bad. You should at least start the subprocess in a restricted user account.
... or a virtualenv.
If you pass universal_newlines=True to the Popen constructor, you can pass str and receive str without explicit encoding to bytes or decoding from bytes; communicate will take str as an argument, and return a two-tuple of str. Mind you, it uses the encoding returned by locale.getpreferredencoding(False), so on some machines (particularly Windows where it's usually something terrible like cp1252 instead of utf-8), you may want to stick with explicit encode and decode steps.
@boardrider: virtualenv provides no security guarantees, it's just to provide a predictable separated environment for Python. Arbitrary user submitted code could effectively undo that virtualization, and even without undoing it, has no special restrictions on what it can do; if the user could do it outside a virtualenv, they can do it inside a virtualenv too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.