~elachuni/piston-mini-client/dual-scheme-support

« back to all changes in this revision

Viewing changes to piston_mini_client/__init__.py

  • Committer: Anthony Lenton
  • Date: 2011-01-20 03:39:17 UTC
  • Revision ID: anthony.lenton@canonical.com-20110120033917-9yrmwi0qjpnjzuvr
- Service_root must use an http or https scheme now.
- _get and _post now have an optional scheme argument.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
import simplejson
7
7
import urllib
8
8
from functools import wraps
 
9
from urlparse import urlparse
9
10
 
10
11
from failhandlers import ExceptionFailHandler, APIError
11
12
 
61
62
 
62
63
 
63
64
class PistonResponseObject(object):
64
 
    """Base class for objects that are returned from api calls.
65
 
    """
 
65
    """Base class for objects that are returned from api calls."""
66
66
    @classmethod
67
67
    def from_response(cls, body, none_allowed=False):
68
68
        data = simplejson.loads(body)
79
79
        return obj
80
80
 
81
81
class PistonSerializable(object):
82
 
    """Base class for objects that want to be used as api call arguments.
83
 
    """
 
82
    """Base class for objects that want to be used as api call arguments."""
84
83
    _atts = ()
85
84
 
86
85
    def __init__(self, **kwargs):
119
118
    def __init__(self, service_root=None, cachedir=None, auth=None):
120
119
        if service_root is None:
121
120
            service_root = self.default_service_root
 
121
        if not service_root:
 
122
            raise ValueError("No service_root provided, and no default found")
 
123
        parsed_service_root = urlparse(service_root)
 
124
        if parsed_service_root.scheme not in ['http', 'https']:
 
125
            raise ValueError("service_root's scheme must be http or https")
122
126
        self._service_root = service_root
 
127
        self._parsed_service_root = list(parsed_service_root)
123
128
        self._cachedir = cachedir
124
129
        self._auth = auth
125
130
 
126
 
    def _get(self, path, args=None):
 
131
    def _get(self, path, args=None, scheme=None):
127
132
        """Perform an HTTP GET request.
128
133
 
129
134
        The provided 'path' is appended to this resource's '_service_root'
131
136
 
132
137
        If provided, 'args' should be a dict specifying additional GET
133
138
        arguments that will be encoded on to the end of the url.
 
139
 
 
140
        'scheme' must be one of 'http' or 'https', and will determine the
 
141
        scheme used for this particular request.  If not provided the
 
142
        service_root's scheme will be used.
134
143
        """
135
144
        if args is not None:
136
145
            if '?' in path:
138
147
            else:
139
148
                path += '?'
140
149
            path += urllib.urlencode(args)
141
 
        return self._request(path, method='GET')
 
150
        return self._request(path, method='GET', scheme=scheme)
142
151
 
143
 
    def _post(self, path, data=None, content_type=None):
 
152
    def _post(self, path, data=None, content_type=None, scheme=None):
144
153
        """Perform an HTTP POST request.
145
154
 
146
155
        The provided path is appended to this api's '_service_root' attribute
153
162
           serializer from serializers.
154
163
 
155
164
        If content_type is None, self.default_content_type will be used.
 
165
 
 
166
        'scheme' must be one of 'http' or 'https', and will determine the
 
167
        scheme used for this particular request.  If not provided the
 
168
        service_root's scheme will be used.
156
169
        """
157
170
        body = data
158
171
        if content_type is None:
163
176
            serializer = get_serializer(content_type)(data)
164
177
            body = serializer.serialize()
165
178
        headers = {'Content-type': content_type}
166
 
        return self._request(path, method='POST', body=body, headers=headers)
 
179
        return self._request(path, method='POST', body=body,
 
180
            headers=headers, scheme=scheme)
167
181
 
168
 
    def _request(self, path, method, body='', headers=None):
 
182
    def _request(self, path, method, body='', headers=None, scheme=None):
169
183
        """Perform an HTTP request.
170
184
 
171
185
        You probably want to call one of the _get, _post methods instead.
173
187
        http = httplib2.Http(cache=self._cachedir)
174
188
        if headers is None:
175
189
            headers = {}
176
 
        url = self._path2url(path)
 
190
        if scheme not in [None, 'http', 'https']:
 
191
            raise ValueError('Invalid scheme %s' % scheme)
 
192
        url = self._path2url(path, scheme=scheme)
177
193
        if self._auth:
178
194
            self._auth.sign_request(url, method, body, headers)
179
195
        try:
189
205
        body = handler.handle(response, body)
190
206
        return body
191
207
 
192
 
    def _path2url(self, path):
193
 
        return self._service_root.rstrip('/') + '/' + path.lstrip('/')
 
208
    def _path2url(self, path, scheme=None):
 
209
        if scheme is None:
 
210
            service_root = self._service_root
 
211
        else:
 
212
            parts = [scheme] + self._parsed_service_root[1:]
 
213
            service_root = urlunparse(parts)
 
214
        return self._service_root.strip('/') + '/' + path.lstrip('/')
194
215