3

I am using Google's Python API to pull down auditing information, but I can't get the parent group arguments for argparse (which appear to be required for API access) and my own arguments (e.g. passing in a date) to work together.

Code:

import pprint
import sys
import re
import httplib2
import json
import collections
import argparse

from oauth2client import client
from apiclient import sample_tools
from apiclient import discovery
from oauth2client.client import AccessTokenRefreshError
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.file import Storage
from oauth2client.tools import run
from oauth2client import tools

def main(argv): 
  # Parser for command-line arguments.
  parser = argparse.ArgumentParser(
  description=__doc__,
  formatter_class=argparse.RawDescriptionHelpFormatter,
  parents=[tools.argparser])

  parser.add_argument("-d","--selected_date", help="Date (YYYY-mm-dd) to run user usage report", required=True)

  args = parser.parse_args(argv[1:])
  print args
  selected_date = args.selected_date
  print selected_date

  # Authenticate and construct service.
  service, flags = sample_tools.init(
  argv, 'admin', 'reports_v1', __doc__, __file__,
  scope='https://www.googleapis.com/auth/admin.reports.usage.readonly')

  # If the Credentials don't exist or are invalid run through the native client
  # flow. The Storage object will ensure that if successful the good
  # Credentials will get written back to a file.
  storage = Storage('admin.dat')
  credentials = storage.get()
  if not credentials or credentials.invalid:
    credentials = run(FLOW, storage)

And running it from the command line...

> python user_report.py
usage: user_report.py [-h] [--auth_host_name AUTH_HOST_NAME]
                  [--noauth_local_webserver]
                  [--auth_host_port [AUTH_HOST_PORT [AUTH_HOST_PORT ...]]]
                  [--logging_level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] -d
                  SELECTED_DATE
user_report.py: error: argument -d/--selected_date is required

Looks good so far... now add an argument

> python user_report.py -d "2014-09-14"
Namespace(auth_host_name='localhost', auth_host_port=[8080, 8090], logging_level='ERROR', noauth_local_webserver=False, selected_date='2014-09-14')
usage: user_report.py [-h] [--auth_host_name AUTH_HOST_NAME]
                  [--noauth_local_webserver]
                  [--auth_host_port [AUTH_HOST_PORT [AUTH_HOST_PORT ...]]]
                  [--logging_level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
user_report.py: error: unrecognized arguments: -d 2014-09-14

It appears that the date argument is not recognized. Any help would be much appreciated!

Alex
  • 397
  • 4
  • 18
  • should you also include userkey as a require arg? https://developers.google.com/resources/api-libraries/documentation/admin/reports_v1/python/latest/admin_reports_v1.userUsageReport.html From the pydocs, it looks like you need more than just date... – Emily Sep 30 '14 at 23:22
  • I add userKey later in the app hard-coded as "all", which brings back events for all users. The code works when I'm not trying to pass in an external argument. thanks! – Alex Oct 01 '14 at 14:15

2 Answers2

3

I have it working now- sample_tools.init is instantiating (for better or worse) its own argparse instance. The Google API allows you to pass in a parent (where I passed in my own custom arguments) and everything is works.

https://google-api-python-client.googlecode.com/hg/docs/epy/apiclient.sample_tools-pysrc.html

# Parser for command-line arguments
parent = argparse.ArgumentParser(add_help=False)
group = parent.add_argument_group('standard')
parent.add_argument("-d","--selected_date", help="Date (YYYY-mm-dd) to run user usage report", required=True)

flags = parser.parse_args(argv[1:])
print flags
selected_date = flags.selected_date
print selected_date

# Authenticate and construct service.
service, flags = sample_tools.init(
  argv, 'admin', 'reports_v1', __doc__, __file__,
  scope='https://www.googleapis.com/auth/admin.reports.usage.readonly', parents=[parent]) 

The extra argument to sample_tools.init (passing the parent) fixes the problem

Alex
  • 397
  • 4
  • 18
  • So you can define your own parser, but you don't run it yourself. That's `sample_tools` job. Do you get the 'selected_date' back via `flags`? – hpaulj Oct 01 '14 at 17:05
  • @hpaulj- Yes, it is accessible as flags.selected_date – Alex Oct 09 '14 at 20:51
1

It looks to me like the following is happening:

args = parser.parse_args(argv[1:])   # runs fine
print args                           # produces the Namespace line
selected_date = args.selected_date
print selected_date                  # where is this output?

# Authenticate and construct service.
service, flags = sample_tools.init(...)  # is this producing the error?

I'm guessing that the tools.argparser is being run by sample_tools.init, and producing the error because it doesn't know about the -d argument.

(I'm familiar with argparse, but not this API).

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • The problem is definitely in here. According to Google, I should be able to override it by passing Oauth2's "parent" (tools.argparser or tools.run_parser) to my own parser. It almost works, but it appears that something later in the chain is not aware of the -d argument – Alex Oct 01 '14 at 14:18