Parsing a variable from command line to a url - python

I have a python script called dlimage. I want to type a variable in terminal like this $ python dlimage.py 1 2 and have 1 and 2 correspond to the the url in download_web_image to become http://www.example.com/1/2.jpg and download the image. How do I go about doing this?
import urllib.request
import argparse
def download_web_image(url):
urllib.request.urlretrieve(url)
parser = argparse.ArgumentParser()
parser.add_argument("num1", "num2")
args = parser.parse_args()
download_web_image("http://www.example.com/"num1"/"num2".jpg")
EDIT 2:
I finally got it to work. Thanks everyone for your help!
Code that worked:
import urllib
import argparse
def download_web_image(url):
IMAGE = url.rsplit('/',1)[1]
urllib.urlretrieve(url, IMAGE)
parser = argparse.ArgumentParser()
parser.add_argument("num1")
parser.add_argument("num2")
args = parser.parse_args()
download_web_image("https://www.example.com/{num1}/{num2}.jpg".format(num1=args.num1, num2=args.num2))

When I try part of your code, I get an error:
In [1663]: parser = argparse.ArgumentParser()
In [1664]: parser.add_argument("num1", "num2")
....
ValueError: invalid option string 'num1': must start with a character '-'
The arguments to the add_argument method are wrong.
What you should be using is:
parser = argparse.ArgumentParser()
parser.add_argument("num1")
parser.add_argument("num2")
In which case the help will look like:
In [1668]: parser.print_help()
usage: ipython3 [-h] num1 num2
positional arguments:
num1
num2
optional arguments:
-h, --help show this help message and exit
and testing an input equivalent to myprog 1 2
In [1669]: args = parser.parse_args(['1','2'])
In [1670]: args
Out[1670]: Namespace(num1='1', num2='2')
In [1671]: args.num1
Out[1671]: '1'
In [1672]: args.num2
Out[1672]: '2'
Now I can format a URL with:
In [1675]: "https://www.example.com/{}/{}.jpg".format(args.num1, args.num2)
Out[1675]: 'https://www.example.com/1/2.jpg'
So there are 2 problems with your code:
Each argument, num1 and num2 has to be defined in a separate add_argument statement. Read the docs to see what else you can add to that statement, such as the help. You are trying to define 2 arguments in one statement, and getting an error.
Secondly you need to use a correct format. I added the {} ({0} and {num1} styles also work). OR in the older Py2 style:
"https://www.example.com/%s/%s.jpg"%(args.num1, args.num2)

Change this
parser.add_argument("num1, "num2")
to
parser.add_argument("num1", "num2")

for this I would use format:
download_web_image("http://www.example.com/{num1}/{num2}.jpg".format(num1=args.num1, num2 = args.num2))
Here is an example:
num1 = 5
num2 = 6
"http://www.example.com/{num1}/{num2}.jpg".format(num1 = num1, num2 = num2)
output:
'http://www.example.com/5/6.jpg'
format makes it easy to insert defined parameters into a string.

Assuming you are using python3, I tried to make something simple and as close to the approach you were trying originally. Hope this helps.
import urllib.request
import sys
def download_web_image(url):
urllib.request.urlretrieve(url)
download_web_image("http://www.example.com/{0}/{1}.jpg".format(sys.argv[1], sys.argv[2]))

I imagine you want to pass N arguments so to generate an URL I would do this :
import sys
args = sys.argv[1:]
baseURL = "http://www.example.com"
url = baseURL + "/" + "/".join(args)
print url
INPUT:
$ python dlimage.py 1 2 3.jpg
OUTPUT:
http://www.example.com/1/2/3.jpg
As for the download, you could try this answer, or read data at the url and write it as a file named as the last argument :
import urllib2
urlResponse = urllib2.urlopen(url)
urlData = urlResponse.read()
outFile = open(args[-1], 'w')
outFile.write(urlData)
outFile.close()
I'm behind a work proxy and I get an error when I download the file, might update my answer later this day at home.

Related

How to pass single String value from Python sub-process code to R Code

I am trying to run a R code from the Python using Subprocess library.
I need to run one .R file from the python and have pass one single String value(args = ["INV28338"]).
I am new in R and so not able to figure out exact data type conversion code in both R and Python.
Please someone help me, how to pass single string/scalar value from Python to R Function/Model ?
Later I will give the shape of 'Flask REST API' for this code.
Thank you so much in advance
Python code:-
import subprocess
command = 'Rscript'
path2script = 'classification_model_code.R'
args = ["INV28338"]
cmd = [command, path2script] + args
x = subprocess.check_output(cmd, universal_newlines=True)
print('The Output is:', x)
R code:-
myArgs <- commandArgs(trailingOnly = TRUE)
nums = as.numeric(myArgs)
invoice_in_scope<-nums
#Followed by more code
my script, test2.R
myArgs <- commandArgs(trailingOnly = TRUE)
nums = as.character(myArgs)
print(nums)
you need to have args as part of the list, so append it to cmd and it works ok:
import subprocess
command = 'Rscript'
path2script = './test2.R'
args = "INV28338"
cmd = [command, path2script]
cmd.append(args)
x = subprocess.check_output(cmd, universal_newlines=True)
print('The Output is:', x)

Python Script Output Changes depending on Computer I am using

I am encountering some weird problem where the same script is outputting a different result. Same python version, same libraries.
Lat=((INPUT_FILE[location[i]+OFFSET+4])<<24|
(INPUT_FILE[location[i]+OFFSET+5])<<16|
(INPUT_FILE[location[i]+OFFSET+6])<<8|
(INPUT_FILE[location[i]+OFFSET+7])<<0)/11930464.71
Long=((INPUT_FILE[location[i]+OFFSET+0])<24|
(INPUT_FILE[location[i]+OFFSET+1])<16|
(INPUT_FILE[location[i]+OFFSET+2])<<8|
(INPUT_FILE[location[i]+OFFSET+3])<<0)/11930464.71
print(Long)
Basically all I am doing is reading bytes from a file and converting them into a coordinate using math. On the Windows computer it is interpreted correctly as a twos complement negative number while on the Linux computer it outputs the value as if it was just an unsigned number. Seems like a Q word D word problem.
import argparse
import os
import stat
import decimal
import sys
import struct
import numpy as np
import re
import binascii
in_file = None
log_file = None
logging = False
FS_MAP = None
PAGE_SIZE = 0x20000
count=0
INPUT_FILE=[]
DirectoryList=""
LIMIT=0
def PreviousDestinatioins ():
print("SCANNING for the Previous Destinations Stored in the pers_NaviControllerLastDestinationsList")
#So lets deal with the first format found in the logs
RegEx = re.compile(binascii.unhexlify("00000000")+b"[\x05-\x0f]"+binascii.unhexlify("00010102"))
location = [m.start(0) for m in RegEx.finditer(INPUT_FILE)]
ARRAY=[]
f.write("<Folder><name>Previous Destinations</name>\n")
for i in range(0,len(location)):
OFFSET=9
Tableoffset=1
print(" ")
STATE=""
CITY=""
ZIPCODE=""
ROAD=""
StreetNumber=""
BusinessName=""
while(Tableoffset!=0x7c12):
TEXT=""
while INPUT_FILE[location[i]+OFFSET]>31:
TEXT=TEXT+chr(INPUT_FILE[location[i]+OFFSET])
OFFSET=OFFSET+1
if Tableoffset==1:
STATE=TEXT
if Tableoffset==0x20215:
OFFSET=OFFSET+20
if Tableoffset==0x201:
CITY=TEXT
if Tableoffset==0x601:
ZIPCODE=TEXT
if Tableoffset==0x301:
ROAD=TEXT
if Tableoffset==0x501:
StreetNumber=TEXT
if Tableoffset==0x11501:
BusinessName=TEXT
Tableoffset=INPUT_FILE[location[i]+OFFSET]<<24|INPUT_FILE[location[i]+OFFSET+1]<<16|INPUT_FILE[location[i]+OFFSET+2]<<8|INPUT_FILE[location[i]+OFFSET+3]
OFFSET=OFFSET+5
address=BusinessName+" "+StreetNumber+" "+ROAD+" "+CITY+" "+STATE+", "+ZIPCODE
print(address)
OFFSET=OFFSET-1
Lat=((INPUT_FILE[location[i]+OFFSET+4])<<24|(INPUT_FILE[location[i]+OFFSET+5])<<16|(INPUT_FILE[location[i]+OFFSET+6])<<8|(INPUT_FILE[location[i]+OFFSET+7])<<0)/11930464.71
Long=((INPUT_FILE[location[i]+OFFSET+0])<<24|(INPUT_FILE[location[i]+OFFSET+1])<<16|(INPUT_FILE[location[i]+OFFSET+2])<<8|(INPUT_FILE[location[i]+OFFSET+3])<<0)/11930464.71
print(str(((INPUT_FILE[location[i]+OFFSET+0])<<24|(INPUT_FILE[location[i]+OFFSET+1])<<16|(INPUT_FILE[location[i]+OFFSET+2])<<8|(INPUT_FILE[location[i]+OFFSET+3])<<0)/11930464.71))
if ((25 <= Lat <= 50) and (-125 <= Long <= -65)):
print("Lat %f"%Lat+" Long %f"%Long)
f.write("<Placemark><Style><IconStyle><scale>2.0</scale><Icon><href>http://maps.google.com/mapfiles/kml/paddle/ylw-blank.png</href></Icon></IconStyle><LabelStyle><scale>.5</scale></LabelStyle></Style><name><![CDATA["+address+"]]></name><Point><altitudeMode>clampToGround </altitudeMode><extrude>0</extrude><coordinates>"+str(Long)+","+str(Lat)+",0</coordinates></Point></Placemark>\n")
f.write("</Folder>\n")
return
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='')
parser.add_argument('-i', '--input', help='Process this input file.', dest='in_file', action='store')
opts = parser.parse_args()
if opts.in_file is None:
print("No input file.")
parser.print_help()
exit(-1)
INPUT_FILE = np.memmap(opts.in_file, mode='r')
FILESIZE=len(INPUT_FILE)
resultstable=[]
f=open("RecoveredGPSData.kml","w")
f.write("<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\"> <Document><name>Recovered GPS Data</name>\n")
print("Filesize is %d"%FILESIZE)
print("Note that this script needs to be modified if looking for coordinates outside of the contential US\n\n\n")
print("This script can take up to five minutes.")
PreviousDestinatioins ()
f.write("</Document></kml>")

Python multiple user arguments to a list

I've got not words to thank you all of you for such great advice. Now everything started to make sense. I apologize for for my bad variable naming. It was just because I wanted to quickly learn and I wont carry out such practices when I write the final script with my own enhancements which will be posted here.
I want to go an another step further by passing the values we've isolated (ip,port,and name) to a template. I tried but couldn't get it right even though I feel close. The text I want to construct looks like this. (
Host Address:<IP>:PORT:<1>
mode tcp
bind <IP>:<PORT> name <NAME>
I have tried this within the working script provided by rahul.(I've edited my original code abiding stackexchange's regulations. Please help out just this once as well. Many thanks in advance.
#!/usr/bin/python
import argparse
import re
import string
p = argparse.ArgumentParser()
p.add_argument("input", help="input the data in format ip:port:name", nargs='*')
args = p.parse_args()
kkk_list = args.input
def func_three(help):
for i in help:
print(i)
for kkk in kkk_list:
bb = re.split(":|,", kkk)
XXX=func_three(bb)
for n in XXX:
ip, port, name = n
template ="""HOST Address:{0}:PORT:{1}
mode tcp
bind {0}:{1} name {2}"""
sh = template.format(ip,port,name)
print sh
orignial post:--
Beginner here. I wrote the below code and it doesn't get me anywhere.
#!/usr/bin/python
import argparse
import re
import string
p = argparse.ArgumentParser()
p.add_argument("INPUT")
args = p.parse_args()
KKK= args.INPUT
bb=re.split(":|,", KKK)
def func_three(help):
for i in help:
#print help
return help
#func_three(bb[0:3])
YY = var1, var2, var3 = func_three(bb[0:3])
print YY
The way to run this script should be "script.py :". i.e: script.py 192.168.1.10:80:string 172.25.16.2:100:string
As you can see if one argument is passed I have no problems. But when there are more arguments I cant determine how to workout the regexes and get this done via a loop.
So to recap, this is how i want the output to look like to proceed further.
192.168.1.10
80
name1
172.25.16.2
100
name2
If there are better other ways to achieve this please feel free to suggest.
I would say what you are doing could be done more simply. If you want to split the input whenever a colon appears you could use:
#!/usr/bin/python
import sys
# sys.argv is the list of arguments you pass when you run the program
# but sys.argv[0] is the actual program name
# so you want to start at sys.argv[1]
for arg in sys.argv[1:]:
listVar = arg.split(':')
for i in listVar:
print i
# Optionally print a new line
print
Please name your variable with respect to context. You will need to use nargs=* for accepting multiple arguments. I have added the updated code below which prints as you wanted.
#!/usr/bin/python
import argparse
import re
import string
p = argparse.ArgumentParser()
p.add_argument("input", help="input the data in format ip:port:name", nargs='*')
args = p.parse_args()
kkk_list = args.input # ['192.168.1.10:80:name1', '172.25.16.2:100:name3']
def func_three(help):
for i in help:
print(i)
for kkk in kkk_list:
bb = re.split(":|,", kkk)
func_three(bb)
print('\n')
# This prints
# 192.168.1.10
# 80
# name1
# 172.25.16.2
# 100
# name3
Updated Code for new requirement
#!/usr/bin/python
import argparse
import re
import string
p = argparse.ArgumentParser()
p.add_argument("input", help="input the data in format ip:port:name", nargs='*')
args = p.parse_args()
kkk_list = args.input # ['192.168.1.10:80:name1', '172.25.16.2:100:name3']
def printInFormat(ip, port, name):
formattedText = '''HOST Address:{ip}:PORT:{port}
mode tcp
bind {ip}:{port} name {name}'''.format(ip=ip,
port=port,
name=name)
textWithoutExtraWhitespaces = '\n'.join([line.strip() for line in formattedText.splitlines()])
# you can break above thing
# text = ""
# for line in formattedText.splitlines():
# text += line.strip()
# text += "\n"
print(formattedText)
for kkk in kkk_list:
ip, port, name = re.split(":|,", kkk)
printInFormat(ip, port, name)
# HOST Address:192.168.1.10:PORT:80
# mode tcp
# bind 192.168.1.10:80 name name1
# HOST Address:172.25.16.2:PORT:100
# mode tcp
# bind 172.25.16.2:100 name name3
Bad variable names aside, if you want to use argparse (which I think is a good habit, even if it is somewhat more complex initially) you should use the nargs='+' option:
#!/usr/bin/env python
import argparse
import re
import string
p = argparse.ArgumentParser()
p.add_argument("INPUT", nargs='+')
args = p.parse_args()
KKK= args.INPUT
def func_three(help):
for i in help:
#print help
return help
for kkk in KKK:
bb=re.split(":|,", kkk)
#func_three(bb[0:3])
YY = var1, var2, var3 = func_three(bb[0:3])
print YY
If you look at the documentation for argparse, you'll notice that there's an nargs argument you can pass to add_argument, which allows you to group more than one input.
For example:
p.add_argument('INPUT', nargs='+')
Would make it so that there is a minimum of one argument, but all arguments will be gathered into a list.
Then you can go through each of your inputs like this:
args = p.parse_args()
for address in args.INPUT:
ip, port = address.split(':')

Python 2.7 mediainfo --inform outputs full info rather than one string

Using the following in powershell produces the expected output of 01:22:02:03:
MediaInfo --Language=raw --Full --Inform="Video;%Duration/String4%" filename
My following python 2.7 script always gives the full mediainfo output with every piece of metadata, not just the Duration String that I specified.. I've tried escaping the semi colons but it has no effect. What am I doing wrong?
import sys
import subprocess
filename = sys.argv[1]
test = subprocess.check_output(['MediaInfo', '--Language=raw', '--Full', '--inform="Video;%Duration/String4%"', filename])
print test
Lose the double-quotes in the --Inform argument. I can reproduce your problem with this code:
import subprocess
args = [
'mediainfo',
'--Language=raw',
'--Full',
'--inform="Video;%Duration/String4%"',
'tests/reference.mp4'
]
bad_output = subprocess.check_output(args)
line_count_bad = len(bad_output.splitlines())
args[3] = args[3].replace('"', '')
good_output = subprocess.check_output(args)
line_count_good = len(good_output.splitlines())
print(line_count_bad, line_count_good, sep='\t')
print(good_output)
The output is:
204 1
b'00:00:07:08\n'

how to input variable into a python script while opening from cmd prompt?

I am wondering how would one get variables inputted in a python script while opening from cmd prompt? I know using c one would do something like:
int main( int argc, char **argv ) {
int input1 = argv[ 0 ]
int input2 = argv[ 1 ]
.....
}
how can I achieve the same kind of result in python?
import sys
def main():
input1 = sys.argv[1]
input2 = sys.argv[2]
...
if __name__ == "__main__":
main()
The arguments are in sys.argv, the first one sys.argv[0] is the script name.
For more complicated argument parsing you should use argparse (for python >= 2.7). Previous modules for that purpose were getopts and optparse.
There are two options.
import sys.argv and use that.
Use getopts
See also: Dive into Python and PMotW
it is also useful to determine option specific variables
''' \
USAGE: python script.py -i1 input1 -i2 input2
-i1 input1 : input1 variable
-i2 input2 : input2 variable
'''
import sys
...
in_arr = sys.argv
if '-i1' not in in_arr or '-i2' not in in_arr:
print (__doc__)
raise NameError('error: input options are not provided')
else:
inpu1 = in_arr[in_arr.index('-i1') + 1]
inpu2 = in_arr[in_arr.index('-i2') + 1]
...
# python script.py -i1 Input1 -i2 Input2

Categories

Resources