executing a python script from another python script - python

I have a script a.py :
#!/usr/bin/env python
def foo(arg1, arg2):
return int(arg1) + int(arg2)
if __name__ == "__main__":
import sys
print foo(sys.argv[1], sys.argv[2])`
I now want to make a script that can run the first script and write the output of a.py to a file with some arguments as well. I want to make the automate_output(src,arglist) generate some kind of an output that I can write to the outfile :
import sys
def automate_output(src, arglist):
return ""
def print_to_file (src, outfile, arglist):
print "printing to file %s" %(outfile)
out = open(outfile, 'w')
s = open(src, 'r')
for line in s:
out.write(line)
s.close()
out.write(" \"\"\"\n Run time example: \n")
out.write(automate(src, arglist))
out.write(" \"\"\"\n")
out.close()
try:
src = sys.argv[1]
outfile = sys.argv[2]
arglist = sys.argv[3:]
automate(src, arglist)
print_to_file(src,outfile,arglist)
except:
print "error"
#print "usage : python automate_runtime.py scriptname outfile args"
I have tried searching around, but so far I do not understand how to pass arguments by using os.system with arguments. I have also tried doing :
import a
a.main()
There I get a NameError: name 'main' is not defined
Update :
I researched some more and found subprocess and I'm quite close to cracking it now it seems.
The following code does work, but I would like to pass args instead of manually passing '2' and '3'
src = 'bar.py'
args = ('2' , '3')
proc = subprocess.Popen(['python', src, '2' , '3'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print proc.communicate()[0]

This is not a function, it's an if statement:
if __name__ == "__main__":
...
If you want a main function, define one:
import sys
def main():
print foo(sys.argv[1], sys.argv[2])`
Then just call it if you need to:
if __name__ == "__main__":
main()

a.main() has nothing to do with if __name__=="__main__" block. The former calls a function named main() from a module, the latter executes its block if current module name is __main__ i.e., when a module is called as a script.
#!/usr/bin/env python
# a.py
def func():
print repr(__name__)
if __name__=="__main__":
print "as a script",
func()
Compare a module executed as a script and a function called from the imported module:
$ python a.py
as a script '__main__'
$ python -c "import a; print 'via import',; a.func()"
via import 'a'
See section Modules in the Python tutorial.
To get output from the subprocess you could use subprocess.check_output() function:
import sys
from subprocess import check_output as qx
args = ['2', '3']
output = qx([sys.executable, 'bar.py'] + args)
print output

Related

Pass arguments to python file which i'm executing from another python file using exec function

I'm trying to execute file1.py from file2 .py by using exec function.
exec(open('file1.py').read())
Now I want to pass parameter target='target.yaml' to file1.py from exec function. How I can do that ?
Please help
You can use subprocess module:
file1:
import subprocess
print("Running file1.py")
subprocess.run("python file2.py target.yaml", shell=True)
exit(0) # file2 will be opened in a new window
file2:
import sys
yaml_file = sys.argv[1]
print("Running file2.py : yaml target: " + yaml_file)
output:
Running file1.py
Running file2.py : yaml target: target.yaml
While the other answer is a very good solution, if you are writing both files yourself you should consider importing one into the other and calling the function from the other file directly.
file1.py:
import otherfile
argument = "Hello world!"
otherfile.fancy_function(argument)
otherfile.py:
def fancy_function(arg):
print(arg)
if __name__ == "__main__":
# If the file is called directly like `python otherfile.py` this will be executed
fancy_function("I have my own world too!")

passing argument from python to subprocess.popen

I have this code:
from subprocess import Popen
link="abc"
theproc = Popen([sys.executable, "p1.py",link])
I want to send the variable "link" to p1.py,
and p1.py will print it.
something like this. here is p1.py:
print "in p1.py link is "+ link
How can I do that?
I'm assuming python refers to Python 2.x on your system.
Retrieve the command line argument in p1.py using sys.argv:
import sys
if not len(sys.argv) > 1:
print "Expecting link argument."
else:
print "in p1.py link is " + sys.argv[1]
There's a function subprocess.check_output that is easier to use if you only want to call a program and retrieve its output:
from subprocess import check_output
output = check_output(["python", "p1.py", "SOME_URL"])
print "p1.py returned the following output:\n'{}'".format(output)
Example output:
$ python call_p1.py
p1.py returned the following output:
'in p1.py link is SOME_URL
'
You have to parse the command line arguments in your p1.py to get it in a variable:
import sys
try:
link = sys.argv[1]
except IndexError:
print 'argument missing'
sys.exit(1)

Calling a python script with arguments using subprocess

I have a python script which call another python script from another directory. To do that I used subprocess.Popen :
import os
import subprocess
arg_list = [project, profile, reader, file, str(loop)]
where all args are string if not converted implicitely
f = open(project_path + '/log.txt','w')
proc = subprocess.Popen([sys.executable, python_script] + arg_list, stdin=subprocess.PIPE, stdout=f, stderr=f)
streamdata = proc.communicate()[0]
retCode = proc.returncode
f.close()
This part works well, because of the log file I can see errors that occurs on the called script. Here's the python script called:
import time
import csv
import os
class loading(object):
def __init__(self, project=None, profile=None, reader=None, file=None, loop=None):
self.project=project
self.profile=profile
self.reader=reader
self.file=file
self.loop=loop
def csv_generation(self):
f=open(self.file,'a')
try:
writer=csv.writer(f)
if self.loop==True:
writer.writerow((self.project,self.profile,self.reader))
else:
raise('File already completed')
finally:
file.close()
def main():
p = loading(project, profile, reader, file, loop)
p.csv_generation()
if __name__ == "__main__":
main()
When I launch my subprocess.Popen, I have an error from the called script which tell me that 'project' is not defined. It looks the Popen method doesn't pass arguments to that script. I think i'm doing something wrong, someone has an idea ?
When you pass parameters to a new process they are passed positionally, the names from the parent process do not survive, only the values. You need to add:
import sys
def main():
if len(sys.argv) == 6:
project, profile, reader, file, loop = sys.argv[1:]
else:
raise ValueError,("incorrect number of arguments")
p = loading(project, profile, reader, file, loop)
p.csv_generation()
We are testing the length of sys.argv before the assignment (the first element is the name of the program).

Calling py script from another py prints the value

Hi I am writing python for the first time:
I have a existing getprop.py script that loads the property file and prints the value of a given property:
import sys
import util
if len(sys.argv) < 3:
print "Error! Usage is: getprop.py [propfile] [propname]"
sys.exit(1)
props = util.loadprops(sys.argv[1])
if sys.argv[2] in props:
print props(sys.argv[2]);
Now I need to get the value of a property in another py script, so I modified the above script such that I do not disturb its functionality and I can use it in another script:
import sys
import util
def getpropvalue(propfile, propname):
props = util.loadprops(propfile)
if propname in props:
return props[propname]
if len(sys.argv) < 3:
print "Error! Usage is: getprop.py [propfile] [propname]"
sys.exit(1)
else:
print getpropvalue(sys.argv[1], sys.argv[2]);
and then in other script I import getprop and call the method like getprop.getpropvalue(FILE_NAME, PROP_NAME)and it prints the value of the property on the screen.
why does it prints the value? Is there any better way to solve this problem?
There is a way to run the script only if it was called directly. Add those lines to the end of your getprop code:
if __name__ == "__main__":
main()
This way the main function is only going to be called if you run the script directly (not importing). Is that what you're looking for?
Some explanation: every running script has a __name__ variable that will be set to "__main__" if you run the script from an IDE or console like python script.py
Change your getprop.py to this:
import sys
import util
def getpropvalue(propfile, propname):
props = util.loadprops(propfile)
if propname in props:
return props[propname]
if __name__ == '__main__':
if len(sys.argv) < 3:
print "Error! Usage is: getprop.py [propfile] [propname]"
sys.exit(1)
else:
print getpropvalue(sys.argv[1], sys.argv[2]);
This will prevent the code from being executed when it is imported.

How can I check with doctest that a program produced certain output?

In one of my functions I'm calling an external program, using subprocess.check_call, which will produce output. How could I use doctest to make sure the output it's producing is the one I'm expecting?
Maybe this can help:
import sys
import tempfile
import subprocess
def example(output):
r""" Do something ...
>>> output = example('Processing file ...')
>>> print output # doctest:+ELLIPSIS
'Processing file ...'
Check how many file was processed.
>>> [line.startswith('Processing file')
... for line in output.splitlines()].count(True)
1
"""
cmd = "print '%s'" % (output, )
with tempfile.TemporaryFile() as output:
subprocess.check_call([sys.executable, '-c', cmd], stdout=output)
output.seek(0)
res = output.read()
return res
if __name__ == '__main__':
import doctest
doctest.testmod()
As you can see i used the argument stdout of the subprocess.check_call function so to be able to get the output of the command , beside that if you are not using the stdout argument (which i assume that is your case) i think it very hard to capture the command output.
Hope this was hopeful :)

Categories

Resources