Skip to content

Commit

Permalink
Get argparser to return help string instead of printing (#30)
Browse files Browse the repository at this point in the history
* NonPrintingParser raises PrintingException instead of printing

* Switch to using NonPrintingParser instead of ArgumentParser

* Test that help/error messages return strings instead of printing

* Check for raising PrintingException instead of SystemExit

* Python 2/3 compatibility for strings
  • Loading branch information
Mackey22 committed Aug 15, 2017
1 parent ab9a189 commit 83c9a2e
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 8 deletions.
2 changes: 2 additions & 0 deletions hca/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ def main():
response = cli.make_request(sys.argv[1:])
if isinstance(response, requests.Response):
print(response.content.decode())
elif type(response) == str:
print(response)
else:
print(json.dumps(response))
13 changes: 13 additions & 0 deletions hca/argument_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import argparse

from .error import PrintingException


class NonPrintingParser(argparse.ArgumentParser):
"""ArgumentParser that will return help and error strings instead of printing."""

def print_usage(self, file=None):
raise PrintingException(self.format_usage())

def print_help(self, file=None):
raise PrintingException(self.format_help())
17 changes: 12 additions & 5 deletions hca/cli.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
from __future__ import absolute_import, division, print_function, unicode_literals

import argparse
import inspect
import pkgutil
import sys

from .added_command import AddedCommand
from .api import autogenerated, composite_commands
from .argument_parser import NonPrintingParser
from .error import PrintingException


class CLI:
"""Class for interacting with users through a CLI."""

def __init__(self, test_api_path=None):
"""Initialize the CLI API."""
self.parser = argparse.ArgumentParser() # Need to add description based on spec.
self.parser = NonPrintingParser() # Need to add description based on spec.
self.commands = {}
subparsers = self.parser.add_subparsers(help='sub-command help')
prefix = autogenerated.__name__ + "."
Expand Down Expand Up @@ -46,9 +47,15 @@ def parse_args(self, command_line_input):
def make_request(self, command_line_input, stream=False):
"""Function to actually make request to api."""
if not command_line_input:
self.parser.print_help()
self.parser.exit(1)
args = self.parse_args(command_line_input)
return self.parser.format_help()

# Handles PrintingException if Base ArgumentParser was going to print.
try:
args = self.parse_args(command_line_input)
except PrintingException as pe:
msg = pe.args[0]
return msg

endpoint = command_line_input[0]

command = self.commands.get(endpoint, None)
Expand Down
7 changes: 7 additions & 0 deletions hca/error.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
class APIException(Exception):
def __init__(self, *args, **kwargs):
super(APIException, self).__init__(*args, **kwargs)


class PrintingException(Exception):
"""NonPrintingParser will raise this to notify CLI to exit and transfer help message (needed for slackbot)."""

def __init__(self, *args, **kwargs):
super(PrintingException, self).__init__(*args, **kwargs)
32 changes: 29 additions & 3 deletions test/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ def test_index_parameters(self):
def test_parsing(self):
"""Test that the parser parses arguments correctly."""
import hca.cli
import hca.error

cli = hca.cli.CLI(os.path.join(os.path.dirname(os.path.realpath(__file__)), "test.json"))

Expand All @@ -171,13 +172,13 @@ def test_parsing(self):
self.assertEqual(cli.parse_args(args), out)

args = ["put-files", "--creator-uid", "1", "--source-url", "sljdf.com", "134"]
self.assertRaises(SystemExit, cli.parse_args, args)
self.assertRaises(hca.error.PrintingException, cli.parse_args, args)

args = ["put-files", "--bundle-uuid", "asdf", "--creator-uid", "1", "--source-url", "sljdf.com"]
self.assertRaises(SystemExit, cli.parse_args, args)
self.assertRaises(hca.error.PrintingException, cli.parse_args, args)

args = ["put-files", "--bundle-uuid", "--creator-uid", "1", "--source-url", "sljdf.com", "134"]
self.assertRaises(SystemExit, cli.parse_args, args)
self.assertRaises(hca.error.PrintingException, cli.parse_args, args)

args = ["get-bundles", "uuid_arg"]
out = {"uuid": "uuid_arg"}
Expand All @@ -197,6 +198,31 @@ def test_parsing(self):
out = {"uuid": "uuid_arg", "replica": "rep"}
self.assertEqual(cli.parse_args(args), out)

def test_cli_printing(self):
import hca.cli
cli = hca.cli.CLI()
string = str if six.PY3 else basestring

# No args given
request = cli.make_request([])
self.assertIsInstance(request, string)

# Base parser help
request = cli.make_request(["-h"])
self.assertIsInstance(request, string)

# Endpoint parser help
request = cli.make_request(["put-bundles", "-h"])
self.assertIsInstance(request, string)

# Base args given incorrectly
request = cli.make_request(["idontbelonghere"])
self.assertIsInstance(request, string)

# Endpoint args given incorrectly
request = cli.make_request(["put-bundles", "idontbelonghere"])
self.assertIsInstance(request, string)

def _get_first_url(self, response):
"""Get the first url we sent a request to if there were redirects."""
if response.history:
Expand Down

0 comments on commit 83c9a2e

Please sign in to comment.