Permalink
Browse files

Improved error handling of errors in session token retrieval, and exp…

…iration.

Version 0.2.5
  • Loading branch information...
1 parent 20afa9c commit 6c4d2296fe2b8e44f34fbe70b64da9b168e53714 @danielhfrank danielhfrank committed Feb 29, 2012
Showing with 237 additions and 58 deletions.
  1. +3 −0 CHANGELOG
  2. +2 −2 asyncdynamo/__init__.py
  3. +28 −13 asyncdynamo/async_aws_sts.py
  4. +203 −42 asyncdynamo/asyncdynamo.py
  5. +1 −1 setup.py
View
@@ -1,3 +1,6 @@
+Version 0.2.5 - 2012-03-05
+ * Improve error handling from STS
+
Version 0.2.4 - 2012-02-23
* Fix RangeKeyAttribute bug in queries
* Add put_item method
View
@@ -28,5 +28,5 @@
except ImportError:
raise ImportError("boto library not installed. Install boto. https://github.com/boto/boto")
-version = "0.2.4"
-version_info = (0, 2, 4)
+version = "0.2.5"
+version_info = (0, 2, 5)
@@ -1,6 +1,6 @@
#!/bin/env python
#
-# Copyright 2010 bit.ly
+# Copyright 2012 bit.ly
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
@@ -26,9 +26,19 @@
import boto
from boto.sts.connection import STSConnection
from boto.sts.credentials import Credentials
+from boto.exception import BotoServerError
+
+class InvalidClientTokenIdError(BotoServerError):
+ '''
+ Error subclass to indicate that the client's token(s) is/are invalid
+ '''
+ pass
class AsyncAwsSts(STSConnection):
'''
+ Class that manages session tokens. Users of AsyncDynamoDB should not
+ need to worry about what goes on here.
+
Usage: Keep an instance of this class (though it should be cheap to
re instantiate) and periodically call get_session_token to get a new
Credentials object when, say, your session token expires
@@ -45,26 +55,35 @@ def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
proxy_user, proxy_pass, debug,
https_connection_factory, region, path, converter)
self.http_client = AsyncHTTPClient()
- # self._auth_handler *should* be set correctly by superclass.
def get_session_token(self, callback):
'''
Gets a new Credentials object with a session token, using this
- instance's aws keys. Callback should operate on the new Credentials obj
+ instance's aws keys. Callback should operate on the new Credentials obj,
+ or else a boto.exception.BotoServerError
'''
return self.get_object('GetSessionToken', {}, Credentials, verb='POST', callback=callback)
def get_object(self, action, params, cls, path="/", parent=None, verb="GET", callback=None):
+ '''
+ Get an instance of `cls` using `action`
+ '''
if not parent:
parent = self
self.make_request(action, params, path, verb,
functools.partial(self._finish_get_object, callback=callback, parent=parent, cls=cls))
- def _finish_get_object(self, response_body, callback, cls=None, parent=None):
+ def _finish_get_object(self, response_body, callback, cls=None, parent=None, error=None):
'''
- Process the body returned by STS. Expect things like network errors to have
- been handled by make_request
+ Process the body returned by STS. If an error is present, convert from a tornado error
+ to a boto error
'''
+ if error:
+ if error.code == 403:
+ error_class = InvalidClientTokenIdError
+ else:
+ error_class = BotoServerError
+ return callback(None, error=error_class(error.code, error.message, response_body))
obj = cls(parent)
h = boto.handler.XmlHandler(obj, parent)
xml.sax.parseString(response_body, h)
@@ -75,12 +94,12 @@ def make_request(self, action, params={}, path='/', verb='GET', callback=None):
Make an async request. This handles the logic of translating from boto params
to a tornado request obj, issuing the request, and passing back the body.
- The callback should operate on the body of the response
+ The callback should operate on the body of the response, and take an optional
+ error argument that will be a tornado error
'''
request = HTTPRequest('https://%s' % self.host,
method=verb)
request.params = params
- # request.path = '/' this one isn't necessary
request.auth_path = '/' # need this for auth
request.host = self.host # need this for auth
if action:
@@ -92,9 +111,5 @@ def make_request(self, action, params={}, path='/', verb='GET', callback=None):
def _finish_make_request(self, response, callback):
if response.error:
- print '!!!!!!!!!!!!!!!!!!!!!!!'
- print response.error
- print response.body
- print '!!!!!!!!!!!!!!!!!!!!!!!'
- return
+ return callback(response.body, error=response.error)
return callback(response.body)
Oops, something went wrong.

0 comments on commit 6c4d229

Please sign in to comment.