Bash style process substitution with Python's Popen
Solution 1:
If pram_axdnull
understands "-"
convention to mean: "read from stdin" then you could:
p = Popen(["pram_axdnull", str(kmer), input_filename, "-"],
stdin=PIPE, stdout=PIPE)
output = p.communicate(generate_kmers(3))[0]
If the input is generated by external process:
kmer_proc = Popen(["generate_kmers", str(kmer)], stdout=PIPE)
p = Popen(["pram_axdnull", str(kmer), input_filename, "-"],
stdin=kmer_proc.stdout, stdout=PIPE)
kmer_proc.stdout.close()
output = p.communicate()[0]
If pram_axdnull
doesn't understand "-"
convention:
import os
import tempfile
from subprocess import check_output
with tempfile.NamedTemporaryFile() as file:
file.write(generate_kmers(3))
file.delete = False
try:
p = Popen(["pram_axdnull", str(kmer), input_filename, file.name],
stdout=PIPE)
output = p.communicate()[0]
# or
# output = check_output(["pram_axdnull", str(kmer), input_filename,
file.name])
finally:
os.remove(file.name)
To generate temporary file using external process:
from subprocess import check_call
with tempfile.NamedTemporaryFile() as file:
check_call(["generate_kmers", str(kmer)], stdout=file)
file.delete = False
To avoid waiting for all kmers to be generated i.e., to write/read kmers simultaneously, you could use os.mkfifo()
on Unix (suggested by @cdarke):
import os
import shutil
import tempfile
from contextlib import contextmanager
from subprocess import Popen, PIPE
@contextmanager
def named_pipe():
dirname = tempfile.mkdtemp()
try:
path = os.path.join(dirname, 'named_pipe')
os.mkfifo(path)
yield path
finally:
shutil.rmtree(dirname)
with named_pipe() as path:
p = Popen(["pram_axdnull", str(kmer), input_filename, path],
stdout=PIPE) # read from path
with open(path, 'wb') as wpipe:
kmer_proc = Popen(["generate_kmers", str(kmer)],
stdout=wpipe) # write to path
output = p.communicate()[0]
kmer_proc.wait()