Solved

Python - command Line how to Args

Posted on 2011-03-16
10
631 Views
Last Modified: 2012-06-27
Hi,

from the commend line I need to execute a file liek this.

test.py daily [YYY-WW-DD-HH]

the date time stamp is optional

Is is the first time I am doing this.

What is the code to get this info?

If the time is optional then revert to current time e.g.

if input_time==None:
 time = now

0
Comment
Question by:dmontgom
  • 3
  • 2
  • 2
  • +2
10 Comments
 
LVL 16

Expert Comment

by:sjklein42
ID: 35153021
http://diveintopython.org/scripts_and_streams/command_line_arguments.html

Each command-line argument passed to the program will be in sys.argv, which is just a list.

Put this in your program to see how the arguments are being passed in:

#argecho.py

import sys

for arg in sys.argv: 
    print arg

Open in new window

0
 

Author Comment

by:dmontgom
ID: 35153068
I am not looking for a link....looking for a solution.  I know how to google.

Here a better link

http://www.doughellmann.com/PyMOTW/getopt/

I am looking for best pratice for handing the case where the second optinal is optional.
0
 

Author Comment

by:dmontgom
ID: 35153254
THis is what I did...but I know its not proper.  What is best practice?

 #job-name = daily | hourly
    if sys.argv[1:][0]=='daily':
        job_type='daily'
    elif sys.argv[1:][0]=='hourly':
        job_type='hourly'
    else:
        print 'job name not specified'
        exit()
       
    #YYYY-MM-DD-HH
    try:
        dt_flag = sys.argv[1:][1]
        if len(dt_flag)!=13:
            print 'date is not in proper format'
            exit()
        now_utc = datetime.datetime.fromtimestamp(time.mktime(time.strptime(dt_flag, "%Y-%m-%d-%H")))
    except:
        now_utc = datetime.datetime.now(timezone('UTC'))
0
 
LVL 8

Expert Comment

by:LunarNRG
ID: 35153712
Best practice? Why didn't you say so? ;)

Although, I'm not sure you'll get consensus.  I tend to think that employing the argparse[1] module (now included in python 3.2) might be considered the best practice (also available as a 3rd party module for previous python versions). It has facilities for optional arguments.

You should really try to avoid using bare excepts, in favor of explicitly specifying the type of exception expected (the latter being the best practice). Otherwise, I don't think there is a whole lot wrong with your approach -- you can simplify it some, perhaps take greater advantage of exception handling. Something like (untested) ...

try:
    job_type, dt_flag = sys.argv[1:]
except ValueError:
    try:
        job_type = sys.argv[1:][0]
    except IndexError:
        print 'job name is a required argument'
        sys.exit(1)
    now_utc = datetime.datetime.now(timezone('UTC'))
else:
    if job_type.lower() not in ('hourly', 'daily'):
        print 'invalid job name'
        sys.exit(1)
    try:
        now_utc = datetime.datetime.fromtimestamp(time.mktime(time.strptime(dt_flag, "%Y-%m-%d-%H")))
    except ValueError:
        print 'date is not in proper format'
        sys.exit(1)

Open in new window


[1] http://docs.python.org/dev/library/argparse.html

HTH
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 8

Expert Comment

by:LunarNRG
ID: 35153763
FWIW, here an example using argparse (also untested) ...

import argparse

def datify(s):
    try:
        return datetime.datetime.fromtimestamp(time.mktime(time.strptime(s, "%Y-%m-%d-%H")))
    except ValueError:
        raise argparse.ArgumentTypeError('date is not in proper format')

parser = argparse.ArgumentParser()
parser.add_argument('jobtype', choices=['hourly', 'daily'])
parser.add_argument('nowutc', type=datify)

args = parser.parse_args()

print args.jobtype
print args.nowutc

Open in new window


0
 
LVL 28

Accepted Solution

by:
pepr earned 125 total points
ID: 35154791
I suggest to start with as simple as possible approach and enhance it later. Try the code below:

a.py
import sys
import time

print sys.argv              # this is a Python list data type

if len(sys.argv) < 2:       # sys.argv[0] is the name of a program/script
    print 'Expecting at least one argument.'
    sys.exit(1)             # terminate immediately
    
frequency = sys.argv[1]     # 'daily' or whatever -- you should test it
theTime = time.localtime()  # default, now

if len(sys.argv) > 2:       # the third argument present
    theTime = time.strptime(sys.argv[2], '%Y-%m-%d-%H')
    
print frequency
print theTime    

Open in new window


You can try to call it like this

C:\tmp\___python\dmontgom\Q_26892495>python a.py
['a.py']
Expecting at least one argument.

C:\tmp\___python\dmontgom\Q_26892495>python a.py daily
['a.py', 'daily']
daily
time.struct_time(tm_year=2011, tm_mon=3, tm_mday=17, tm_hour=10, tm_min=0, tm_sec=51, tm_wday=3, tm_yday=76, tm_isdst=0)

C:\tmp\___python\dmontgom\Q_26892495>python a.py daily 2011-03-11-10
['a.py', 'daily', '2011-03-11-10']
daily
time.struct_time(tm_year=2011, tm_mon=3, tm_mday=11, tm_hour=10, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=70, tm_isdst=-1)

C:\tmp\___python\dmontgom\Q_26892495>python a.py daily cripledTS
['a.py', 'daily', 'cripledTS']
Traceback (most recent call last):
  File "a.py", line 14, in <module>
    theTime = time.strptime(sys.argv[2], '%Y-%m-%d-%H')
  File "c:\Python27\lib\_strptime.py", line 454, in _strptime_time
    return _strptime(data_string, format)[0]
  File "c:\Python27\lib\_strptime.py", line 325, in _strptime
    (data_string, format))
ValueError: time data 'cripledTS' does not match format '%Y-%m-%d-%H'

Open in new window


I am not sure if the format of the timestamp is what you really want (not clear from the question).

I suggest to add the try/except construct only when you are sure why -- see the last example.  Also, there is no need for datetime manipulation unless you want do do some calculation where working with the time structure is not enough.

A side note: I can see no reason for using expressions like sys.argv[1:][0].  This is simply sys.argv[1] only extracted by more complex way.
0
 
LVL 28

Expert Comment

by:pepr
ID: 35154808
0
 
LVL 8

Assisted Solution

by:LunarNRG
LunarNRG earned 125 total points
ID: 35157091
There are potentially even more problems, but these few stood out to me after re-reading my posts -- and it's safe to assume both remain untested. I've also included a few notes, as comments in the code. Please ask questions, if you need additional clarification.

#!/usr/bin/env python
import sys, datetime
from pytz import timezone

# take only the first 2 arguments, if less than 2 check for one
try: 
    # this will ignore arguments after the 2nd
    job_type, dt_flag = sys.argv[1:3]
except ValueError:
    # take the first argument, exit if not given
    try: 
        # pepr is right about [1:][0] vs [1]
        job_type = sys.argv[1]
    except IndexError:
        print 'job name is a required argument'
        sys.exit(1)
    # default value for optional argument
    now_utc = datetime.datetime.now(timezone('UTC'))
else:
    # restrict choices of first argument
    if job_type not in ('hourly', 'daily'):
        print 'invalid job name'
        sys.exit(1)
    try:
        # datetime objects now have a strptime method, starting w/ python 2.5
        now_utc = datetime.datetime.strptime(dt_flag, "%Y-%m-%d-%H")
    except ValueError:
        print 'date is not in proper format'
        sys.exit(1)

Open in new window


Sample output:

$ ./args2.py 
job name is a required argument
$ ./args2.py daily
daily
2011-03-17 14:53:39.420964+00:00
$ ./args2.py daily 2011-01-01-01
daily
2011-01-01 01:00:00
$ ./args2.py daily 2011-01-01
date is not in proper format
$ ./args2.py monthly 2011-01-01-01
invalid job name

Open in new window


#!/usr/bin/env python
import argparse, datetime
from pytz import timezone

# argparse handles most of the drudgery of dealing with 
# command-line options and arguments, as you can see ...

# you can define your own "type" functions in argparse, very useful
def convert_to_date(strng):
    try:
        return datetime.datetime.strptime(strng, "%Y-%m-%d-%H")
    except ValueError:
        raise argparse.ArgumentTypeError('date is not in proper format')

parser = argparse.ArgumentParser()
parser.add_argument('jobtype', choices=['hourly', 'daily'], metavar='JOBTYPE', help='The job name.')
# default value, used when the 2nd arg is not passed
parser.add_argument(
    'nowutc', nargs='?', type=convert_to_date, metavar='TIMESTAMP',
    default=datetime.datetime.now(timezone('UTC')), help='Timestamp [optional]'
)

args = parser.parse_args()

print args.jobtype
print args.nowutc

Open in new window


Sample output:

$ ./args.py
usage: args.py [-h] JOBTYPE [TIMESTAMP]
args.py: error: too few arguments
$ ./args.py daily
daily
2011-03-17 14:53:35.128120+00:00
$ ./args.py daily 2011-01-01-01
daily
2011-01-01 01:00:00
$ ./args.py daily 2011-01-01
usage: args.py [-h] JOBTYPE [TIMESTAMP]
args.py: error: argument TIMESTAMP: date is not in proper format
$ ./args.py monthly 2011-01-01-01
usage: args.py [-h] JOBTYPE [TIMESTAMP]
args.py: error: argument JOBTYPE: invalid choice: 'monthly' (choose from 'hourly', 'daily')
$ ./args.py -h
usage: args.py [-h] JOBTYPE [TIMESTAMP]

positional arguments:
  JOBTYPE     The job name.
  TIMESTAMP   Timestamp [optional]

optional arguments:
  -h, --help  show this help message and exit

Open in new window

0
 
LVL 31

Expert Comment

by:James Murrell
ID: 36515798
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Installing Python 2.7.3 version on Windows operating system For installing Python first we need to download Python's latest version from URL" www.python.org " You can also get information on Python scripting language from the above mentioned we…
Here I am using Python IDLE(GUI) to write a simple program and save it, so that we can just execute it in future. Because when we write any program and exit from Python then program that we have written will be lost. So for not losing our program we…
Learn the basics of strings in Python: declaration, operations, indices, and slicing. Strings are declared with quotations; for example: s = "string": Strings are immutable.: Strings may be concatenated or multiplied using the addition and multiplic…
Learn the basics of while and for loops in Python.  while loops are used for testing while, or until, a condition is met: The structure of a while loop is as follows:     while <condition>:         do something         repeate: The break statement m…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

27 Experts available now in Live!

Get 1:1 Help Now