How can I do this? I use Biopython and saw manual already. Of course I can make blastdb from FASTA using "makeblastdb" in standalone NCBI BLAST+, but I want to whole process in one program.
It seems there are two possible solutions.
Find a function which perform this job.
I cannot find this. I've spent whole day.
Run "makeblastdb" in python.
I input os.system("C:\blast-2.2.25+\bin\makeblastdb.exe") in my python shell, but I couldn't give any parameters.
How can I solve this?
Thank you for your helping.
This is classic Blast, but I think the idea stays the same. Code is extracted from my application KimBlast. I think it is self-explaining:
def on_execute_setup(self, evt):
"""on pressing execute button"""
FORMAT_EXE = os.path.join(self.blastpath, 'bin', 'formatdb')
fasta = os.path.join(self.dbpath, self.fasta)
format_filename = self.format_file.rsplit('.', 1)[0]
format_filepath = os.path.join(self.dbpath, format_filename)
format_type = 'T' if self.format_type == 'protein' else 'F'
format_cmd = '%s -i %s -p %s -n %s' % (FORMAT_EXE, fasta,
format_type, format_filepath)
process = subprocess.Popen(format_cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=False)
(out, err) = process.communicate()
Related
First, I'm not a developer. I'm trying to split a movie into 1 minute clips usinf ffmpeg-split.py python script. I made sure FFmpeg is installed it trying a simple command and it worked like magic:
ffmpeg -i soccer.mp4 -ss 00:00:00 -codec copy -t 10 soccer1.mp4
A new video file was created in the same folder.
I saved the FFmpeg-split.py in the same dir, updated python PATH and typed the following command:
python ffmpeg-split.py -f soccer.mp4 -s 10
what I got back was:
can't determine video length
I believe it just can't find the file. I switched video files and even deleted it and got the same message.
Any ideas?
first time I've seen that name!? Because I believe you were able to run ffmpeg from the command line and execute basic python stuff I recommend following my example as it should avoid any weird directory.connection.stuff in the given file (which i ignored). "Earlier that day": Let me ignore the .py script and share as follows:
Assuming you ran
ffmpeg -i soccer.mp4 ...stuff... soccer1.mp4
from a windows.command.line...
It would be better to write
ffmpeg -t 10 -i "Z:\\full\\input\\path.mp4" -c copy "Z:\\full\\output\\path.mp4"
This says, run ffmpeg, -t=input.duration.seconds, -i=input.file.next,
"fullinpath" in quotes cause spaces etc., -c=all.codecs, copy=atlantian.magic.trick,
"fulloutpath" also to be safe, nothing else!
"Piping" through python to windows works great for this:
import subprocess as subprocess
def pegRunner(cmd): #Takes a list of strings we'll pass to windows.
command = [x for x in cmd] # peg short for mpeg, shoulda used meg.gem.gepm.gipper.translyvania.otheroptions
result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output, err = result.communicate()
print result.wait()
return "pegRannered"
#########
# Find the duration from properties or something. If you need to do this
# often it's more complicated. Let's say you found 4mins33secs.
############
leng = 4*60+33 # time in seconds
last_dur = int(leng%60) #remaining time after the 4 one.min.vids
if last_dur == 0: num_vids = int(leng/60)
else: num_vids = int(leng/60)+1
for i in range(num_vids):
da_command = ['ffmpeg']
da_command.append('-ss')
da_command.append(str(i*60))
da_command.append('-t')
if i != num_vids: da_command.append('60')
else: da_command.append(str(last_dur))
da_command.append('-i')
da_command.append('Z:\\full\\input\\path.mp4') #this format!
da_command.append('-c')
da_command.append('copy')
#optionally to overwrite!!!! da_command.append('-y')
da_command.append('Z:\\full\\output\\path\\filename_'+str(i)+'.mp4')
print pegRunner(da_command)
print "Finished "+str(i)+" filez."
This should handle the 1.min pieces and provide a good starting place for ffmpeg from python.
Struggling with this for literally two weeks. I can't get this .zip to unpack. I know that it is correct because I can make it work in a standard command line and it in shows everything that I know is in it. Trying to unpack a zip and then rename and copy portions of that file to another folder. Here is the basic setup:
import subprocess
cmd = ['7z', 'e', 'site']
sp = subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
After that import I try and unpack it using:
sp.communicate([cmd, 'r"C:\Users\boster\desktop\data1.zip"'])
now it gets past this point because it moves onto my if else section but it doesn't unpack it. I know that it will run the following because it gets to the end and returns my else statement and then prompts me to run the data again.
if "sz + business_date" == name:
shutil.copy(sz%s) % business_date
os.renames(sales.xls)
shutil.copy(sc%s) % business_date
os.renames(cosales.xls)
shutil.copy(aj%s) % business_date
os.renames(money.xls)
shutil.copy(cc%s) % business_date
os.renames(count.xls)
else:
print "Repoll %s for %s" % (item, business_date)
print "Once information is downloaded press enter."
re_download = raw_input(" ")
data_one()
I've left out some of the stuff like the business_date portions because it's returning that as a variable in the else so I know it's grabbing that information correctly. I just have no idea why this won't unpack. Please help. If this isn't sufficient I'll upload the whole module if you'd like.
I finally managed to get this to work. It wasn't unpacking on the subprocess.communicate and since call can't be used with PIPE I just dumped all the commands at the beggining and ended up with the following.
def extract_data_one():
for item in sites:
os.chdir(r"\\svr-dc\ftp site\%s\Daily" % item)
subprocess.call(['7z', 'e', 'data1.zip', '*.*'])
Thanks for all your help.
I encountered a similar problem when using 7zip compressed file with subprocess, I solved my problem by another way. This is my code,
def zip_files_in_special_path(rom_path, rom_name):
pre_cwd = os.getcwd()
os.chdir(rom_path)
cmd_str = r'C:\7-Zip\7z a -tzip -r '+rom_name+' *'
try:
status = os.system(cmd_str)
if status<=1:
return True
else:
raise RunCmdError('run 7z to zip files failed!')
finally:
os.chdir(pre_cwd)
hope to help you.
This question from years ago does what I need:
How do I check out a file from perforce in python?
but is there a way to do this using the subprocess module? (which I understand is the preferred way)
I've looked through stackoverflow, the python docs, as well as many google searches trying to find a way to use the stdin to send the required input to the p4 process, but I've not been successful. I've been able to find plenty on capturing the output of a subprocess command, but have not been able to grok the input commands.
I'm pretty new to python in general, so I am likely missing something obvious, but I don't know what I don't know in this case.
This is the code I've come up with so far:
descr = "this is a test description"
tempIn = tempfile.TemporaryFile()
tempOut = tempfile.TemporaryFile()
p = subprocess.Popen(["p4","change","-i"],stdout=tempOut, stdin=tempIn)
tempIn.write("change: New\n")
tempIn.write("description: " + descr)
tempIn.close()
(out, err) = p.communicate()
print out
As I mentioned in my comment, use the Perforce Python API.
Regarding your code:
tempfile.TemporaryFile() isn't usually appropriate for creating a file and then passing the contents off to something else. The temporary file is automatically deleted as soon as the file is closed. Often you need to close the file for writing before you can re-open it for reading, creating a catch-22 situation. (You can get around this with tempfile.NamedTemporaryFile(delete=False), but that's still too round-about for this situation.)
To use communicate(), you need to pass subprocess.PIPE:
descr = "this is a test description"
changespec = "change: New\ndescription: " + descr
p = subprocess.Popen(["p4","change","-i"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(out, err) = p.communicate(changespec)
print out
if stdout is not unlimited then use #Jon-Eric's answer otherwise replace p.communicate() with rc = p.wait(); tempOut.seek(0); chunk = tempOut.read(chunk_size) ....
I am trying to run grep command from my Python module using the subprocess library. Since, I am doing this operation on the doc file, I am using Catdoc third party library to get the content in a plan text file. I want to store the content in a file. I don't know where I am going wrong but the program fails to generate a plain text file and eventually to get the grep result. I have gone through the error log but its empty. Thanks for all the help.
def search_file(name, keyword):
#Extract and save the text from doc file
catdoc_cmd = ['catdoc', '-w' , name, '>', 'testing.txt']
catdoc_process = subprocess.Popen(catdoc_cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
output = catdoc_process.communicate()[0]
grep_cmd = []
#Search the keyword through the text file
grep_cmd.extend(['grep', '%s' %keyword , 'testing.txt'])
print grep_cmd
p = subprocess.Popen(grep_cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
stdoutdata = p.communicate()[0]
print stdoutdata
On UNIX, specifying shell=True will cause the first argument to be treated as the command to execute, with all subsequent arguments treated as arguments to the shell itself. Thus, the > won't have any effect (since with /bin/sh -c, all arguments after the command are ignored).
Therefore, you should actually use
catdoc_cmd = ['catdoc -w "%s" > testing.txt' % name]
A better solution, though, would probably be to just read the text out of the subprocess' stdout, and process it using re or Python string operations:
catdoc_cmd = ['catdoc', '-w' , name]
catdoc_process = subprocess.Popen(catdoc_cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
for line in catdoc_process.stdout:
if keyword in line:
print line.strip()
I think you're trying to pass the > to the shell, but that's not going to work the way you've done it. If you want to spawn a process, you should arrange for its standard out to be redirected. Fortunately, that's really easy to do; all you have to do is open the file you want the output to go to for writing and pass it to popen using the stdout keyword argument, instead of PIPE, which causes it to be attached to a pipe which you can read with communicate().
How can we sftp a file from source host to a destinition server in python by invoking unix shell commands in python script using os.system...Please help
I have tried the following code
dstfilename="hi.txt"
host="abc.com"
user="sa"
os.system("echo cd /tmp >sample.txt)
os.system("echo put %(dstfilename)s" %locals()) // line 2
os.system("echo bye >>sample.txt")
os.system("sftp -B /var/tmp/sample.txt %(user)s#%(host)s)
How to append this result of line to sample.txt?
os.system("echo put %(dstfilename)s %locals()) >>sample.txt" // Seems this is syntatically not correct.
cat>sample.txt //should look like this
cd /tmp
put /var/tmp/hi.txt
bye
Any help?
Thanks you
You should pipe your commands into sftp. Try something like this:
import os
import subprocess
dstfilename="/var/tmp/hi.txt"
samplefilename="/var/tmp/sample.txt"
target="sa#abc.com"
sp = subprocess.Popen(['sftp', target], shell=False, stdin=subprocess.PIPE)
sp.stdin.write("cd /tmp\n")
sp.stdin.write("put %s\n" % dstfilename)
sp.stdin.write("bye\n")
[ do other stuff ]
sp.stdin.write("put %s\n" % otherfilename)
[ and finally ]
sp.stdin.write("bye\n")
sp.stdin.close()
But, in order to answer your question:
os.system("echo put %(dstfilename)s %locals()) >>sample.txt" // Seems this is syntatically not correct.
Of course it isn't. You want to pass a stringto os.system. So it has to look like
os.system(<string expression>)
with a ) at the end.
The string expression consists of a string literal with an applied % formatting:
"string literal" % locals()
And the string literal contains the redirection for the shell:
"echo put %(dstfilename)s >>sample.txt"
And together:
os.system("echo put %(dstfilename)s >>sample.txt" % locals())
. But as said, this is the worst solution I can imagine - better write directly to a temp file or even better pipe directly into the sub process.
Well, I think the literal solution to your question would look something like this:
import os
dstfilename="/var/tmp/hi.txt"
samplefilename="/var/tmp/sample.txt"
host="abc.com"
user="sa"
with open(samplefilename, "w") as fd:
fd.write("cd /tmp\n")
fd.write("put %s\n" % dstfilename)
fd.write("bye\n")
os.system("sftp -B %s %s#%s" % (samplefilename, user, host))
As #larsks says, use a proper filehandler to make the tmp file for you, and my personal preference is to not to do string formatting using locals().
However depending on the use case, I don't think this is a particularly suitable approach - how does the password the sftp site get entered for example?
I think you'd get a more robust solution if you took a look at the SFTPClient in Paramiko, or failing that, you might need something like pexpect to help with ongoing automation.
If you want a non-zero return code if any of the sftp commands fail, you should write the commands to a file, then run an sftp batch on them. In this fashion, you can then retrieve the return code to check if the sftp commands had any failure.
Here's a quick example:
import subprocess
host="abc.com"
user="sa"
user_host="%s#%s" % (user, host)
execute_sftp_commands(['put hi.txt', 'put myfile.txt'])
def execute_sftp_commands(sftp_command_list):
with open('batch.txt', 'w') as sftp_file:
for sftp_command in sftp_command_list:
sftp_file.write("%s\n" % sftp_command)
sftp_file.write('quit\n')
sftp_process = subprocess.Popen(['sftp', '-b', 'batch.txt', user_host], shell=False)
sftp_process.communicate()
if sftp_process.returncode != 0:
print("sftp failed on one or more commands: {0}".format(sftp_command_list))
Quick disclaimer: I did not run this in a shell so a typo might be present. If so, send me a comment and I will correct.