Search code examples
pythontypescriptdeno

How to run a Python Script from Deno?


I have a python script with the following code:

print("Hello Deno")

I want to run this python script (test.py) from test.ts using Deno. This is the code in test.ts so far:

const cmd = Deno.run({cmd: ["python3", "test.py"]});

How can I get the output, of the python script in Deno?


Solution

  • To execute a python script from Deno you need to use Deno.Command

    const command = new Deno.Command('python3', {
      args: [ "test.py" ],
    });
    const { code, stdout, stderr } = await command.output();
    console.log(new TextDecoder().decode(stdout));
    console.log(new TextDecoder().decode(stderr));
    

    Old answer: Deno.run is now deprecated in favor of Deno.Command

    Deno.run returns an instance of Deno.Process. In order to get the output use .output(). Don't forget to pass stdout/stderr options if you want to read the contents.

    // --allow-run
    const cmd = Deno.run({
      cmd: ["python3", "test.py"], 
      stdout: "piped",
      stderr: "piped"
    });
    
    const output = await cmd.output() // "piped" must be set
    const outStr = new TextDecoder().decode(output);
    
    const error = await cmd.stderrOutput();
    const errorStr = new TextDecoder().decode(error);
    
    cmd.close(); // Don't forget to close it
    
    console.log(outStr, errorStr);
    

    If you don't pass stdout property you'll get the output directly to stdout

     const p = Deno.run({
          cmd: ["python3", "test.py"]
     });
    
     await p.status();
     // output to stdout "Hello Deno"
     // calling p.output() will result in an Error
     p.close()
    

    You can also send the output to a File

    // --allow-run --allow-read --allow-write
    const filepath = "/tmp/output";
    const file = await Deno.open(filepath, {
          create: true,
          write: true
     });
    
    const p = Deno.run({
          cmd: ["python3", "test.py"],
          stdout: file.rid,
          stderr: file.rid // you can use different file for stderr
    });
    
    await p.status();
    p.close();
    file.close();
    
    const fileContents = await Deno.readFile(filepath);
    const text = new TextDecoder().decode(fileContents);
    
    console.log(text)
    

    In order to check status code of the process you need to use .status()

    const status = await cmd.status()
    // { success: true, code: 0, signal: undefined }
    // { success: false, code: number, signal: number }
    

    In case you need to write data to stdin you can do it like this:

    const p = Deno.run({
        cmd: ["python", "-c", "import sys; assert 'foo' == sys.stdin.read();"],
        stdin: "piped",
      });
    
    
    // send other value for different status code
    const msg = new TextEncoder().encode("foo"); 
    const n = await p.stdin.write(msg);
    
    p.stdin.close()
    
    const status = await p.status();
    
    p.close()
    console.log(status)
    

    You'll need to run Deno with: --allow-run flag in order to use Deno.run