How to execute Python code without having to write it to a file?

http.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
params := req.URL.Query();
fmt.Println(params.Get(“Appp”));

f, _ := os.Create("./samples1.py")
// check(err)
defer f.Close()

w := bufio.NewWriter(f)

_, _ = fmt.Fprintf(w, "%s\n", params.Get("Appp"))
// check(err)
w.Flush()
cmd := exec.Command("python", "samples1.py")

We are getting python code from html file using ajax call and then writing that data into some .py file in backend
Then we are executing that .py file using Go lang with cmd := exec.Command(“python”, “samples1.py”)

I need to run the python code without creating new files**(here samples1.py)** at backend using Go lang

is there any way to do this …plzz help me with this
@NobbZ
@lutzhorn
@calmh

You mentioned me again, I really do not like that. Please do not run through the streets yelling my name!

Also, please try to correctly format your code examples, it was hard to find your actuall question in that blob of letters.

After that has been said, its simple as writing the script to pythons stdin. The process is very similar to what I showed you in the other Thread, but you should use Cmd.Start() instead of Cmd.Run() then.

Aside of that you really shouldn’t run arbitrary user-supplied code on your machine without properly sandboxing it. If you need to ask how, I’d suggest to consult professionals that help you to build your application from the ground.

2 Likes

This question is not related to Go, it is a Python question.

Python has this option:

-c command
Specify the command to execute (see next section). This terminates the option list (following options are passed as arguments to the command).

And:

when called with -c command, it executes the Python statement(s) given as command. Here command may contain multiple statements separated by newlines. Leading whitespace is significant in Python statements! In non-interactive mode, the entire input is parsed before it is executed.

see https://linux.die.net/man/1/python

So if you want to use Python code from Go as input to the Python interpreter, you can do something like this:

package main

import (
	"fmt"
	"log"
	"os/exec"
)

func main() {
	var code = `# Python code
a = 1
b = 2
c = a + b
print(c)
`

	cmd := exec.Command("/usr/bin/python3.5", "-c", code)

	out, err := cmd.CombinedOutput()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Python output:\n%s", out)
}

But where is the IDE? Like in this topic you refer to an IDE but your posts speak about something else. In this case look like a launcher :thinking:

I don’t think this question is about an IDE. It is about executing Python code from Go. I’ve changed the topic to reflect this.

2 Likes

Hey…Thank you for the response… I have done exactly same thing…but the problem comes when the code takes input arguments…i can take inputs in go program but i don’t know how to correlate the python code and the inputs…TIA

Do you mean input to the Python code? What form does the input have?

  • Does your code read from STDIN?
  • Do you use command line arguments?
  • Or maybe environment variables?
  • Or (please no) interactive usage?
http.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
params := req.URL.Query();
fmt.Println(params.Get("pythonCode")); //contains python code retrieved by calling ajax call
fmt.Println(params.Get("argument")); //contains arguments(inputs) retrieved by calling ajax call

cmd := exec.Command("python","-c", params.Get("pythonCode")) //how can i use this command along with the inputs
stdout, _ := cmd.StdoutPipe()
stderr, _ := cmd.StderrPipe()
                                                                                                                                                                                   
cmd.Start(); 

This is my code…i used to execute my python file which doesnt take any input arguments using the above code…and now i want to send input arguments and then execute the file…

As you probably know, command line arguments are read in Python using the sys.argv list. You will only have to make sure that in your Go code you pass params.Get( "argument") as a list to exec.Command.

basically i am trying to make a python compiler. So i expect the person to write a normal code with user inputs. So i have to execute the code with his inputs and send back the output. So i cant use sys.argv as the code is written by the user.

i am taking code and inputs from user by ajax call in json format…any further help would be appreciated

Its a bit complicated, since everythinig you pass in as CLI-arguments will be consumed by python, if though it does behave as many other tools, you can stop its own arg-parser by giving double dash (--) as argument, every argument from then should be passed into the run script then:

exec.Command("python", "-c", script, "--", args...)

And again, this is a guess based on common behaviour of many CLI-tools, I do not give away any gurantee that this will work. Python is not in the (huge) set of languages I do use.

1 Like

Traceback (most recent call last):
File “”, line 1, in
EOFError: EOF when reading a line

i am getting above error when tried this

exec.Command("python","-c", params.Get("pythonCode") , "--" , params.Get("userInput"))

You should try to get this running without all the HTTP overhead. Start simple. Just put your Python code into a simple string in your Go code. Don’t use any further arguments. Does it work?

If it does work, you can take the next step. Add -- and one argument to you call to exec.Command. Try to read this argument in your Python code using sys.argv. Does it work?

If it does work, you can take the next step. Add more arguments and try to get them from a list. Does it work?

I had some time to spare while switching working sites…

It seems to be even worse… When you run a script using python -c, you will get passed in every single argument, except the script itself:

$ python -c "import sys; print sys.argv" foo
['-c', 'foo']

When piping the script from stdin and you want to use arguments, you need to specify - as input file, which is then passed in to the script as well:

echo "import sys; print sys.argv" | python - foo bar
['-', 'foo', 'bar']

If you save a file, and run it, you will get that filename as well:

$ echo "import sys; print sys.argv" > foo.py
$ python foo.py foo bar
['foo.py', 'foo', 'bar']

By adding a shebang, making it executable and running it directly I do get the name of the script as well:

$ ./foo.py bar baz
['./foo.py', 'bar', 'baz']

Having the actual script name as first element is kind of expected for me, but also I had expected it to be None or a similar value for the -c and pipe cases. (Compare to argv[0] in C)

Especially awkward seems to be, that python swallows some arguments silently.

I wasn’t able to reproduce your error message though. Therefore I have to assume you are passing in an erroronous script…


edit

And after thinking about it a bit I think we can rely on - and -c as script names as well to check how that file has been called…

1 Like

This is not a question about Go.