Clean up doc strings, formatting, and unused code

This commit is contained in:
Garrett Holmstrom 2013-02-20 15:38:39 -08:00
parent 8bd312fdff
commit b59b6a19a1
8 changed files with 69 additions and 97 deletions

View File

@ -34,6 +34,12 @@ ISO8601 = '%Y-%m-%dT%H:%M:%SZ'
class BaseAuth(object):
'''
Basis for all authentication
This class does nothing on its own. It is up to you to implement the
necessary functions to effect an authentication scheme.
'''
ARGS = []
def __init__(self, service, **kwargs):
@ -62,6 +68,9 @@ class BaseAuth(object):
class HmacKeyAuth(BaseAuth):
'''
Basis for AWS HMAC-based authentication
'''
ARGS = [Arg('-I', '--access-key-id', dest='key_id', metavar='KEY_ID',
route_to=AUTH),
Arg('-S', '--secret-key', dest='secret_key', metavar='KEY',

View File

@ -35,29 +35,27 @@ from .util import aggregate_subclass_fields
class BaseCommand(object):
'''
The basis for a command line tool. To invoke this as a command line tool,
call the do_cli() method on an instance of the class; arguments will be
parsed from the command line. To invoke this in another context, pass
keyword args to __init__() with names that match those stored by the
argument parser and then call main().
call the run() method on the class. Arguments will be parsed from the
command line. To invoke this in another context, such as from inside
another command, pass keyword arguments to __init__() with names that match
those stored by the argument parser and then call main() to retrieve a
result.
Important methods in this class include:
- do_cli: command line entry point
- main: processing
- print_result: format data from the main method and print it to stdout
To be useful a tool should inherit from this class and implement the main()
and print_result() methods. The do_cli() method functions as the entry
point for the command line, populating self.args from the command line and
then calling main() and print_result() in sequence. Other tools may
instead supply arguments via __init__() and then call main() alone.
The general workflow of a command involves two methods: main(), which
inspects the arguments stored in self.args, does something, and returns a
result; and print_result(), which takes the output of main() and prints it
to stdout. By default, both of these methods do nothing. It is up to you
to implement them to do what the tool is designed to do.
Important members of this class include:
- DESCRIPTION: a string describing the tool. This becomes part of the
command line help string.
- Args: a list of Arg and/or MutuallyExclusiveArgGroup objects
- DESCRIPTION: a string that describes the tool. This becomes part of
the command line help string.
- USAGE: a usage message for the command line help string. If this
is None, one will be generated automatically.
- ARGS: a list of Arg and/or MutuallyExclusiveArgGroup objects
are used to generate command line arguments. Inheriting
classes needing to add command line arguments should
contain their own Args lists, which are *prepended* to
contain their own ARGS lists, which are combined with
those of their parent classes.
'''
@ -244,9 +242,6 @@ class BaseCommand(object):
def name(self):
return self.__class__.__name__
def print_result(self, data):
pass
def main(self):
'''
The main processing method. main() is expected to do something with
@ -254,6 +249,12 @@ class BaseCommand(object):
'''
pass
def print_result(self, data):
'''
Take a result produced by main() and print it to stdout.
'''
pass
@property
def debug(self):
if self.__config_enables_debugging():

View File

@ -16,6 +16,7 @@ from __future__ import absolute_import
import logging
class ProgressiveStreamHandler(logging.StreamHandler):
'''
A handler class that allows the "cursor" to stay on one line for selected
@ -45,6 +46,7 @@ class ProgressiveStreamHandler(logging.StreamHandler):
except Exception:
self.handleError(record)
class ColoringFormatter(logging.Formatter):
LOG_COLORS = [(logging.ERROR, '\033[91m'),
(logging.WARN, '\033[93m'),
@ -58,6 +60,7 @@ class ColoringFormatter(logging.Formatter):
return colorcode + msg + '\033[0m'
return msg
def configure_root_logger(use_color=False):
logfmt = '%(asctime)s %(levelname)-7s %(name)s %(message)s'
rootlogger = logging.getLogger('')

View File

@ -15,6 +15,7 @@
from . import Arg
from .command import BaseCommand
class TabifyingCommand(BaseCommand):
'''
A request mixin that provides the tabify() function along with its

View File

@ -27,49 +27,45 @@ from .service import BaseService
from .util import aggregate_subclass_fields
from .xmlparse import parse_listdelimited_aws_xml
class BaseRequest(BaseCommand):
'''
The basis for a command line tool that represents a request. To invoke
this as a command line tool, call the do_cli() method on an instance of the
class; arguments will be parsed from the command line. To invoke this in
another context, pass keyword args to __init__() with names that match
those stored by the argument parser and then call main().
The basis for a command line tool that represents a request. The data for
this request are stored in a few instance members:
- method: the HTTP method to use (e.g. 'GET'). Defaults to self.METHOD.
- path: the path to append to the service's path (e.g. 'sub/dir')
- headers: a dict of HTTP headers
- params: a dict of query parameters
- body: a string or file object containing a request body, or a dict
to pass to the server as form data
Important methods in this class include:
- do_cli: command line entry point
- main: pre/post-request processing and request sending
- send: actually send a request to the server and return a
response (called by the main() method)
- print_result: format data from the main method and print it to stdout
This specialization of BaseCommand that implements main() as a three-step
process:
- preprocess(): do any processing needed before sending the request,
such as parsing complex command line arguments and
storing them in self.params, self.headers, and so forth.
- send(): send this request to the server using the data stored
in its attributes, parse it using self.parse_result(),
and return it
- postprocess(): given a parsed response, do any processing needed before
main() returns the response.
To be useful a tool should inherit from this class and implement the main()
and print_result() methods. The do_cli() method functions as the entry
point for the command line, populating self.args from the command line and
then calling main() and print_result() in sequence. Other tools may
instead supply arguments via __init__() and then call main() alone.
Most requests need only implement preprocess(). Requests whose workflows
involve sending other requests often do so in postprocess(), where the
result of the request is known.
Important members of this class include:
- SERVICE_CLASS: a class corresponding to the web service in use
- NAME: a string containing the Action query parameter. This
defaults to the class's name.
- DESCRIPTION: a string describing the tool. This becomes part of the
command line help string.
- ARGS: a list of Arg and/or MutuallyExclusiveArgGroup objects
are used to generate command line arguments. Inheriting
classes needing to add command line arguments should
contain their own Args lists, which are *prepended* to
those of their parent classes.
- FILTERS: a list of Filter objects that are used to generate filter
options at the command line. Inheriting classes needing
to add filters should contain their own FILTERS lists,
which are *prepended* to those of their parent classes.
Important members of this class, in addition to those inherited from
BaseCommand, include:
- SERVICE_CLASS: a class corresponding to the web service in use
- NAME: a string representing the name of this request. This
defaults to the class's name.
- METHOD: the HTTP method to use by default
'''
SERVICE_CLASS = BaseService
NAME = None
METHOD = 'GET'
FILTERS = []
LIST_MARKERS = []
@ -110,10 +106,6 @@ class BaseRequest(BaseCommand):
@property
def name(self):
'''
The name of this action. Used when choosing what to supply for the
Action query parameter.
'''
return self.NAME or self.__class__.__name__
@property
@ -177,9 +169,7 @@ class BaseRequest(BaseCommand):
The main processing method for this type of request. In this method,
inheriting classes generally populate self.headers, self.params, and
self.body with information gathered from self.args or elsewhere,
call self.send, and return the response. BaseRequest's default
behavior is to simply return the result of a request with everything
that routes to PARAMS.
call self.send, and return the response.
'''
self.preprocess()
response = self.send()
@ -205,6 +195,7 @@ class BaseRequest(BaseCommand):
class AWSQueryRequest(BaseRequest):
API_VERSION = None
FILTERS = []
def populate_parser(self, parser, arg_objs):
BaseRequest.populate_parser(self, parser, arg_objs)
@ -250,7 +241,7 @@ class AWSQueryRequest(BaseRequest):
transform each element in the dict that matches the corresponding
arg routing table into a simple dict containing key-value pairs
suitable for use as query parameters. This implementation flattens
dicts and lists into the format given by the EC2 query API, which uses
dicts and lists into the format given by AWS query APIs, which use
dotted lists of dict keys and list indices to indicate nested
structures.

View File

@ -27,6 +27,7 @@ import weakref
from .exceptions import ClientError, ServiceInitError
from .util import aggregate_subclass_fields
class BaseService(object):
NAME = ''
DESCRIPTION = ''

View File

@ -17,6 +17,7 @@ import requests
import sys
from . import __version__
def aggregate_subclass_fields(cls, field_name):
values = []
# pylint doesn't know about classes' built-in mro() method
@ -26,39 +27,3 @@ def aggregate_subclass_fields(cls, field_name):
if field_name in vars(m_class):
values.extend(getattr(m_class, field_name))
return values
def get_default_user_agent():
user_agent = ['requestbuilder/{0}'.format(__version__)]
tokens = []
impl = platform.python_implementation()
if impl == 'PyPy':
impl_version = '{0}.{1}.{2}'.format(
sys.pypy_version_info.major,
sys.pypy_version_info.minor,
sys.pypy_version_info.micro)
if sys.pypy_version_info.releaselevel != 'final':
impl_version += sys.pypy_version_info.releaselevel
else:
# I'm guessing for non-CPython implementations; feel free to submit
# patches or the needed implementation-specific API references.
impl_version = platform.python_version()
tokens.append('{0} {1}'.format(impl, impl_version))
plat = []
try:
plat.append(platform.system())
plat.append(platform.release())
except IOError:
pass
if plat:
tokens.append(' '.join(plat))
tokens.append(platform.machine())
user_agent.append('({0})'.format('; '.join(tokens)))
try:
# This should always work; I'm just being paranoid.
user_agent.append('requests/{0}'.format(requests.__version__))
except:
pass
return ' '.join(user_agent)

View File

@ -17,6 +17,7 @@ try:
except ImportError:
from xml.etree import ElementTree
def parse_aws_xml(xml_stream, list_item_markers=None):
'''
Parse a stream of XML and return a nested dict. The dict represents each