1

I am still a newbie to python, so apologies in advance. I have related topics on this but didn't find the best solution. (Run a python script from another python script, passing in args) Basically, I have a python script (scriptB.py) that takes in a config file as argument and does some stuff. I need to call this script from another python script (scriptA.py).

If I had no arguments to pass, I could have just done

import scriptB.py

However, things got little complicated because we need to pass the config file (mycnofig.yml) as argument.

One of the suggestions was to use;

os.system(python scriptB.py myconfig.yml)

But, it is often reported as not a recommended approach and that it often does not work.

Another suggestion was to use:

import subprocess
subprocess.Popen("scriptB.py myconfig.yaml", shell=True)

I am not very sure if this is a common practice.

Just want to point out that both scripts don't have any main inside the script.

Please advise on the best way to handle this.

Thanks,

Aisha
  • 91
  • 7

3 Answers3

1

this should work just fine

subprocess.Popen(['python', '/full_path/scriptB.py', 'myconfig.yaml'], stdout=PIPE, stderr=PIPE)

See https://docs.python.org/3/library/subprocess.html#replacing-os-popen-os-popen2-os-popen3

Jodast
  • 1,279
  • 2
  • 18
  • 33
0

If you really need to run a separate process, using the multiprocessing library is probably best. I would make an actual function inside scriptB.py that does the work. In the below example I consider config_handler to be a function inside scriptB.py that actually takes the config file path argument.

1.) create a function that will handle the calling of your external python script, also, import your script and the method inside it that takes arguments

scriptA.py: importing config_handler from scriptB

import multiprocessing
from scriptB import config_handler

def other_process(*args):
    p = multiprocessing.Process(*args)
    p.start()

2.) Then just call the process and feed your arguments to it:

scriptA.py: calling scriptB.py function, config_handler

other_process(name="config_process_name", target=config_handler, args=("myconfig.yml",))

Opinion:

From the information you have provided, i imagine you could manage to do this without separate processes. Just do things all in sequence and make scriptB.py a library with a function you use in scriptA.py.

Community
  • 1
  • 1
aramnhammer
  • 135
  • 2
  • 9
0

It seems you got all your answers in the old thread, but if you really want to run it through os, not through python, this is what I do:

from subprocess import run, PIPE, DEVNULL

your_command = './scriptB.py myconfig.yaml'
run(your_command.split(), stdout=PIPE, stderr=DEVNULL)

In case you need the output:

output = run(your_command.split(), stdout=PIPE, stderr=DEVNULL).stdout.decode('utf-8')

If the scriptB has the shebang header telling the bash its a python script, it should run it correctly.

Path can be both relative and absolute.

It is for Python 3.x