7z will not find archive using subprocess - 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.

Related

Im not sure how to take filename out of sha256 checksum in Python 3

I'm still a Python noob but figured that instead of checking a checksum manually, I would make a quick program so it would take less time whenever I had to do it(also as practice) so I wrote this(excuse the extra useless lines and bad naming in my code, I was trying to pinpoint what I was doing wrong.)
import subprocess
FileLocation = input("Enter File Location: ")
Garbage1 = str(input("Enter First Checksum: "))
Garbage2 = str(subprocess.call(['sha256sum', FileLocation]))
Garbage3 = Garbage2.split(None, 1)
if Garbage1 == Garbage3[0]:
print("all good")
else:
print("Still Not Working!!!")
When I run this code it keeps on leaving the filepath at the end of the second checksum because of the Linux command, but I tried getting rid of it various ways with .split() but when I ran the code, it was still there, I also tried to add the file path to the end of the first checksum as a test, but that also won't add the filepath to the end of it.
I do know for a fact that the checksums match
Any idea whats wrong any help would be appreciated.
From the docs, subprocess.call does: Run command with arguments. Wait for command to complete or timeout, then return the returncode attribute. You can verify this in the python shell by entering help(subprocess.call) or looking at https://docs.python.org and searching for the subprocess module.
Your code converts the integer return code to a string, not the checksum. There are other calls in subprocess that capture the process stdout, which is where sha256sum sends its checksum. Stdout is a bytes object that needs to be decoded to a string.
import subprocess
FileLocation = input("Enter File Location: ")
Garbage1 = str(input("Enter First Checksum: "))
Garbage2 = subprocess.check_output(['sha256sum', FileLocation]).decode()
Garbage3 = Garbage2.split(None, 1)
if Garbage1 == Garbage3[0]:
print("all good")
else:
print("Still Not Working!!!")

Python call to external software command

I have a slight problem. I have a software which has a command with two inputs. The command is: maf2hal inputfile outputfile.
I need to call this command from a Python script. The Python script asks the user for path of input file and path of output file and stores them in two variables.The problem is that when I call the command maf2hal giving the two variable names as the arguments, the error I get is cannot locate file.
Is there a way around this? Here's my code:
folderfound = "n" # looping condition
while (folderfound == "n"):
path = raw_input("Enter path of file to convert (with the extension) > ")
if not os.path.exists(path):
print "\tERROR! file not found. Maybe file doesn't exist or no extension was provided. Try again!\n"
else:
print "\tFile found\n"
folderfound = "y"
folderfound = "y" # looping condition
while (folderfound == "y"):
outName = raw_input("Enter path of output file to be created > ")
if os.path.exists(outName):
print "\tERROR! File already exists \n\tEither delete the existing file or enter a new file name\n\n"
else:
print "Creating output file....\n"
outputName = outName + ".maf"
print "Done\n"
folderfound = "n"
hal_input = outputName #inputfilename, 1st argument
hal_output = outName + ".hal" #outputfilename, 2nd argument
call("maf2hal hal_input hal_output", shell=True)
This is wrong:
call("maf2hal hal_input hal_output", shell=True)
It should be:
call(["maf2hal", hal_input, hal_output])
Otherwise you're giving "hal_input" as the actual file name, rather than using the variable.
You should not use shell=True unless absolutely necessary, and in this case it is not only unnecessary, it is pointlessly inefficient. Just call the executable directly, as above.
For bonus points, use check_call() instead of call(), because the former will actually check the return value and raise an exception if the program failed. Using call() doesn't, so errors may go unnoticed.
There are a few problems. Your first reported error was that the call to the shell can't find the maf2hal program - that sounds like a path issue. You need to verify that the command is in the path of the shell that is being created.
Second, your call is passing the words "hal_input" and "hal_output". You'll need to build that command up first to pass the values of those variables;
cmd = "maf2hal {0} {1}".format(hal_input, hal_output)
call(cmd, shell=True)
Your code is literally trying to open a file called hal_input, not using the contents of your variable with the same name. It looks like you're using the subprocess module to execute, so you can just change it to call(["maf2hal", hal_input, hal_output], shell=True) to use the contents.
at the end of your code:
call("maf2hal hal_input hal_output", shell=True)
you are literally calling that string, not the executable and then those paths, you need to concatenate your strings together first, either by adding them of using .join
eg:
call("maf2hal " + hal_input + " " + hal_output", shell=True)
or
call("maf2hal ".join(hal_input, " ", hal_output), shell=True)

Python: Adding Variable paths into os.system("open"+filename)

I'm trying to make a script where python goes through a directory, finds all files that ends with *ref.SDAT, and then opens them all.
So far, I have the sorting of files process. The wanted files are put into reflist:
import os
import glob
import subprocess
os.chdir("/Users/BabyJ/Desktop/MRSDATA")
reflist = glob.glob('*raw_ref.SDAT')
print "These are the ref files:"
for i in reflist:
os.system('open+%s') %i
I don't know how to structure the syntax so that os.system will open all of the components of the list though.
The % operator wants the 'open+%s' string as its left-hand side. You are offering it the return value of os.system(). Also, I think you wanted a space, not a + in the string.
Try this:
os.system('open %s'%i)
I assuming judging from your use of open that you are on a Mac or Unix system. If that is the case use either of the following to get you up and running.
for i in reflist:
os.system('open ' + '%s' % i)
or:
for i in reflist:
subprocess.call('open ' + '%s' % i, shell = True)
Using subprocess is the better solution as os.system is, though not technically gone from the language, deprecated in Python per the official documentation.
Hope that helps.
EDIT:
If you're using windows sub in start for open.

Communicate with Rar.exe in Python

From a Python script I want to create a RAR file. I will need to communicate with Rar.exe because I only want the first RAR volume from a multi-volume archive set, nothing more. The -vp switch makes sure Create next volume ? [Y]es, [N]o, [A]ll is asked after each volume. The first time this question pops up, I want to answer No. How do I accomplish this?
I've been reading and trying a lot of things and I found out something like this can be accomplished with pexpect. I've been trying the two different Windows ports: wexpect and winpexpect. The result is that my script will hang. No RAR file is created. This is my code:
import wexpect
import sys
rarexe = "C:\Program Files\WinRAR\Rar.exe"
args = ['a', '-vp', '-v2000000b', 'only_first.rar', 'a_big_file.ext']
child = wexpect.spawn(rarexe, args)
child.logfile = sys.stdout
index = child.expect(["Create next volume ? [Y]es, [N]o, [A]ll",
wexpect.EOF, wexpect.TIMEOUT], timeout=10)
if index == 0:
child.sendline("N")
else:
print('error')
Other approaches are welcome too.
I had the same issue, because there are several (buggy) version of wexpect on the web.
Check out of my variant, which is a copy of an instance, which worked for me.
This can be installed using
pip install wexpect
The answer to my problem has two parts.
As betontalpfa indicated, I must use his version of wexpect. It can be installed easily:
pip install wexpect
The expect_exact documentation of Pexpect explains that it uses plain string matching instead of compiled regular expressions patterns in the list. This means the parameters must be properly escaped or the expect_exact method must be used instead of expect. It gave me this working code:
import wexpect
import sys
rarexe = "C:\Program Files\WinRAR\Rar.exe"
args = ['a', '-vp', '-v2000000b', 'only_first.rar', 'a_big_file.ext']
child = wexpect.spawn(rarexe, args)
# child.logfile = sys.stdout
rar_prompts = [
"Create next volume \? \[Y\]es, \[N\]o, \[A\]ll",
"\[Y\]es, \[N\]o, \[A\]ll, n\[E\]ver, \[R\]ename, \[Q\]uit",
wexpect.EOF, wexpect.TIMEOUT]
index = child.expect(rar_prompts, timeout=8)
while index < 2:
# print(child.before)
if index == 0:
print("No next volume")
child.sendline("N")
elif index == 1:
print("Overwriting existing volume")
child.sendline("Y")
index = child.expect(rar_prompts, timeout=8)
else:
print('Index: %d' % index)
if index == 2:
print("Success!")
else:
print("Time out!")
And the output gives:
Overwriting existing volume
No next volume
Index: 2
Success!

Making Blast database from FASTA in Python

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()

Categories