Python pass a file as argument - python

I've been working on a Python problem for sometime now. I'm trying to use the Echoprint API to sort my music out. So i'm writing some code that does that for me.
This is how the API works :
Takes in a song name as a command line arg.
Gives the appropriate result.
But i'm writing a script that has to perform this "internally". As in, the script should take the files and perform the lookup and output the results to the terminal. (basically - NO COMMAND LINE ARGUMENTS SUPPLIED )
So is there anyway as to pass files into a function ?
I know this sounds silly but it's a problem i'm not able to solve.
If i use os.walk(), etc it returns a str object to my lookup function as a parameter. I want the audio file to be passed as a parameter.
Here's the code which takes in the song as a command line arg :
import sys
import os
import pyechonest.config as config
import pyechonest.song as song
config.CODEGEN_BINARY_OVERRIDE = os.path.abspath("/Users/******/python/minger/echoprint-codegen-master/echoprint-codegen")
config.ECHO_NEST_API_KEY='*****'
def lookup(file):
# Note that song.identify reads just the first 30 seconds of the file
fp = song.util.codegen(file)
if len(fp) and "code" in fp[0]:
# The version parameter to song/identify indicates the use of echoprint
result = song.identify(query_obj=fp, version="4.11")
print "Got result:", result
print result[0]
if len(result):
print "Artist: %s (%s)" % (result[0].artist_name, result[0].artist_id)
print "Song: %s (%s)" % (result[0].title, result[0].id)
else:
print "No match. This track may not be in the database yet."
else:
print "Couldn't decode", file
if __name__ == "__main__":
if len(sys.argv) < 2:
print >>sys.stderr, "Usage: %s <audio file>" % sys.argv[0]
sys.exit(1)
lookup(sys.argv[1])

From there, http://echonest.github.io/remix/apidocs/pyechonest.util-module.html#codegen
the method you use has signature
codegen(filename, start=0, duration=30)
so that it is the filename that has to be passed as an argument... not the file itself...
Ex use here http://nullege.com/codes/show/src#p#y#pyechonest-7.1.0#pyechonest#song.py/371/util.codegen
if filename:
if os.path.exists(filename):
query_obj = util.codegen(filename, start=codegen_start, duration=codegen_duration)
if query_obj is None:
raise Exception("The filename specified: %s could not be decoded." % filename)

Related

Not able to send input argument values using subprocess Python Windows 10

I am running a main script on windows 10 that calls another script called audioplayer.py using the subprocess module in python.
I want to send some input arguments when calling the audioplayer.py. So I wrote the main script as follows:
The following is the main script:
from subprocess import call
call(["python", "C:/Users/Jeff/Documents/audioplayer.py", "hey.wav"])
The following is my audioplayer.py:
"""OpenAL playback example."""
import os, sys, time
from openal.audio import SoundSink, SoundSource
from openal.loaders import load_wav_file
if len (sys.argv) < 2:
print ("Usage: %s wavefile" % os.path.basename(sys.argv[0]))
print (" Using an example wav file...")
dirname = os.path.dirname(__file__)
fname = os.path.join(dirname, "default.wav")
else:
fname = sys.argv[1]
sink = SoundSink()
sink.activate()
source = SoundSource(position=[10, 0, 0])
source.looping = True
data = load_wav_file(fname)
source.queue(data)
sink.play(source)
source.position = [source.position[0], source.position[1], source.position[2]]
sink.update()
time.sleep(2)
print("playing at %r" % source.position)
But I keep getting the following error even though the file does exist in the same directory as audioplayer.py
FileNotFoundError: [Errno 2] No such file or directory: 'hey.wav'
If I remove the hey.wav in the main script, it runs fine. It just doesn't seem to take any arguments.
try this:
call(["python", "C:/Users/Jeff/Documents/audioplayer.py", "C:/Users/Jeff/Documents/hey.wav"])
When you run the last one, the dir is the same with the main.py instead of the audioplayer.py.

python script not working on cmd

This is a simple code, its function is extracting the metadata of certain images. However, it would work on any linux machine via the terminal fine as expected, whether printing the metadata into the terminal or saving the result into a text file.
When it comes to CMD on windows which is the primary OS for my PC wouldn't work, even the shell IDLE for Python it doesn't create the file or even print out the metadata.
codes explanation, takes two parameters, name of image, and out << means whether it's supposed to output the data into the terminal or into a specified text file.
I can't actually spot where the problem is!!
Please help me to identify the issue !! Thanks
Here's the code:
from time import sleep
import argparse
from PIL import Image
from PIL.ExifTags import TAGS
def getMetaData(imgname, out):
"""supported format of images are: .JPG, .TIF & .WAV"""
try:
metaData = {} # dictionary to hold the tags
imgFile = Image.open(imgname)
print "Getting meta data..."
info = imgFile._getexif()
if info:
print "Found Meta Data! "
for (tag, value) in info.items():
tagname = TAGS.get(tag, tag) # to human readable format
metaData[tagname] = value
if not out:
print tagname, value
if out:
print "outputting to file ..."
with open(out, "w") as f:
for (tagname, value) in metaData.items():
f.write(str(tagname)+'\t'+str(value)+"\n")
except:
print "Failed!!"
def Main():
print "Coded By: GentleMan"
print "Created 2/24/2017"
print "Use it carefully baby"
print "Special for x6x.net"
sleep(3)
parser = argparse.ArgumentParser()
parser.add_argument("img", help="Name of an image File")
parser.add_argument("--output","-o", help="dump data out to File.")
args = parser.parse_args()
if args.img:
print getMetaData(args.img, args.output)
else:
print parser.usage
if __name__ == '__main__':
Main()

Python Command Line Arguments Try/Except

I want to create a program that will take two command line arguments. The first being the name of a file to open for parsing and the second the flag -s. If the user provides the wrong number of arguments or the other argument is not -s then it will print the message "Usage: [-s] file_name" and terminate the program using exit.
Next, I want my program to attempt to open the file for reading. The program should open the file read each line and return a count of every float, integer, and other kinds of strings that are not ints or floats. However, if opening the file fails it should raise an exception and print "Unable to open [filename]" and quit using exit.
I've been looking up lots of stuff on the internet about command lines in Python but I've ended up more confused. So here's my attempt at it so far from what I've researched.
from optparse import OptionParser
def command_line():
parser = OptionParser()
parser.add_option("--file", "-s")
options, args = parser.parse_args()
if options.a and obtions.b:
parser.error("Usage: [-s] file_name")
exit
def read_file():
#Try:
#Open input file
#Except:
#print "Unable to open [filename]"
#Exit
from optparse import OptionParser
import sys,os
def command_line():
parser = OptionParser("%prog [-s] file_name")
parser.add_option("-s",dest="filename",
metavar="file_name",help="my help message")
options, args = parser.parse_args()
if not options.filename:
parser.print_help()
sys.exit()
return options.filename
def read_file(fn):
if os.path.isfile(fn):
typecount = {}
with open(fn) as f:
for line in f:
for i in line.split()
try:
t = type(eval(i))
except NameError:
t = type(i)
if t in typecount:
typecount[t] += 1
else:
typecount[t] = 1
else:
print( "Unable to open {}".format(fn))
sys.exit()
print(typecount)
read_file(command_line())
So step by step:
options.a is not defined unless you define an option --a or (preferably) set dest="a".
using the built-in parser.print_help() is better than making your own, you get -h/--help for free then.
you never called your function command_line, therefore never getting any errors, as the syntax was correct. I set the commandline to pass only the filename as a return value, but there are better ways of doing this for when you have more options/arguments.
When it comes to read_file, instead of using try-except for the file I recommend using os.path.isfile which will check whether the file exists. This does not check that the file has the right format though.
We then create a dictionary of types, then loop over all lines and evaluate objects which are separated by whitespace(space,newline,tab). If your values are separated by eg. a comma, you need to use line.split(',').
If you want to use the counts later in your script, you might want to return typecount instead of printing it.

Encountering issues when executing a command at terminal from python

I have the following command.
/usr/bin/node_modules/phantomjs/bin/phantomjs RequestURL.js https://www.ubank.com.au/ > body.html which gets executed fine at the terminal, but does not get executed from python as follows.
def get_generated_html(self, url, has_headers):
"""
Method: Method to get the generated HTML content from Phantomas.
Args: Takes the url as an argument for which to get the HTML content.
hasHeaders defaulted to false for no headers.
Returns: Nothing.
"""
if not urlparse(url).scheme:
url = 'http://'+url
if has_headers == False:
command = PAGE_SOURCE_CMD % url
utils.execute_command(command).communicate()
else:
command = FEO_PAGE_SOURCE_CMD % url
print command
utils.execute_command(command).communicate()
The print statement prints out the exact command.
Here is the execute_command() method.
def execute_command(command):
"""Executes the command and returns the process."""
process = None
try:
process = subprocess.Popen(command, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
except subprocess.CalledProcessError:
print (
'Process utility could not process %s'
' inside execute_command() method'
% url)
return process
I call the generated html as follows.
def start_parser(self, analysis_id, url, hasHeaders=False):
"""
Method: Method to start the parser.
Args: Analsyis ID and URL as an argument.
Returns: Nothing.
"""
feed = None
path = self.create_analysis_folder(analysis_id, hasHeaders)
self.get_generated_html(url, hasHeaders)
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith('.html'):
feed = BeautifulSoup(open(path + '/' +file).read())
if hasHeaders:
os.chdir('..')
print "deleting"
shutil.rmtree(os.getcwd())
break
return feed
The feed returned here is not the page source as it returns from command line.
I'm not sure what get_generated_html is supposed to do, but it doesn't return anything and it only prints in one of the cases. I'm confused by the docstring, since it says the function shouldn't return anything, but it doesn't say anyting about output either. The "defaults to false" part is not correct in the current code.
Also, communicate returns a tuple, so you will only return one of the elements of the return value (probably).
Try something like:
output = utils.execute_command(command).communicate()
return output[0]
If we are doing code review, this is more elegant to me:
if not has_headers:
command = PAGE_SOURCE_CMD % url
else:
command = FEO_PAGE_SOURCE_CMD % url
output = utils.execute_command(command).communicate()
return output[0] # or print it?

Git diff is complaining, "external diff died, stopping at ... " with my python diff program

Here's the beginning part of my diff.
#!/usr/bin/env python
import fileinput
import difflib
import subprocess
import sys
# for debugging
def info(type, value, info):
import traceback
traceback.print_exception(type, value, info)
print
pdb.pm()
sys.excepthook = info
import pdb
#end debugging
if len(sys.argv) == 8:
# assume this was passed to git; we can of course do
# some parsing to check if we got valid git style args
args = [sys.argv[2], sys.argv[5]]
elif len(sys.argv) == 3:
args = sys.argv[1:]
else:
exit("Not a valid number of args (2 or 7) to this diff program")
print "Files: " + ' '.join(args)
for filename in args:
filetype = subprocess.check_output(['file', filename])
if filetype.find('text') == -1:
args.insert(0, 'diff')
print "A binary file was found: " + filename + ", deferring to diff"
exit(subprocess.call(args))
When a binary (or otherwise non text) file is encountered, it attempts to fork diff to obtain whether the binary files differ or not. The goal is for this python diff program to be used as an external differ for git.
But I get this ghastly "external diff died, stopping at <file>" message once it hits the binary file.
How is git evaluating my program? How does it know it died? Isn't return value supposed to indicate the differing condition?
There's no exit function in your code. How about replace exit to sys.exit?
#!/usr/bin/env python
import subprocess
import sys
if len(sys.argv) == 8:
# assume this was passed to git; we can of course do
# some parsing to check if we got valid git style args
args = [sys.argv[2], sys.argv[5]]
elif len(sys.argv) == 3:
args = sys.argv[1:]
else:
print "Not a valid number of args (2 or 7) to this diff program"
sys.exit(1)
print "Files: ", args
for filename in args:
filetype = subprocess.check_output(['file', filename])
if filetype.find('text') == -1:
args.insert(0, 'diff')
print "A binary file was found: " + filename + ", deferring to diff"
#sys.stdout.flush()
subprocess.call(args)
sys.exit(0)
EDIT: git depend on external diff's exit status. diff exit with 0 only if there is no differce. So changed the code not to use diff's exit status.
PS: Without sys.stdout.flush(), diff output come before print output.

Categories

Resources