Package restkit :: Module resource
[hide private]
[frames] | no frames]

Source Code for Module restkit.resource

  1  # -*- coding: utf-8 - 
  2  # 
  3  # This file is part of restkit released under the MIT license.  
  4  # See the NOTICE for more information. 
  5   
  6   
  7  """ 
  8  restkit.resource 
  9  ~~~~~~~~~~~~~~~~ 
 10   
 11  This module provide a common interface for all HTTP request.  
 12  """ 
 13   
 14  import urlparse 
 15   
 16  from restkit.errors import ResourceNotFound, Unauthorized, RequestFailed,\ 
 17  ParserError, RequestError 
 18  from restkit.client import HttpConnection 
 19  from restkit.filters import BasicAuth 
 20  from restkit import util 
 21  from restkit.pool.simple import SimplePool 
 22   
23 -class Resource(object):
24 """A class that can be instantiated for access to a RESTful resource, 25 including authentication. 26 """ 27 28 charset = 'utf-8' 29 encode_keys = True 30 safe = "/:" 31 pool_class = SimplePool 32 keepalive = True 33 basic_auth_url = True 34
35 - def __init__(self, uri, headers=None, **client_opts):
36 """Constructor for a `Resource` object. 37 38 Resource represent an HTTP resource. 39 40 :param uri: str, full uri to the server. 41 :param headers: dict, optionnal headers that will 42 be added to HTTP request. 43 :param client_opts: `restkit.client.HttpConnection` Options 44 """ 45 46 pool_instance = client_opts.get('pool_instance') 47 if not pool_instance and self.keepalive: 48 pool = self.pool_class() 49 client_opts['pool_instance'] = pool 50 51 if self.basic_auth_url: 52 # detect credentials from url 53 u = urlparse.urlparse(uri) 54 if u.username: 55 password = u.password or "" 56 57 # add filters 58 filters = client_opts.get('filters', []) 59 filters.append(BasicAuth(u.username, password)) 60 client_opts['filters'] = filters 61 62 # update uri 63 uri = urlparse.urlunparse((u.scheme, u.netloc.split("@")[-1], 64 u.path, u.params, u.query, u.fragment)) 65 66 self.uri = uri 67 self._headers = headers or {} 68 self.client_opts = client_opts 69 self._body_parts = []
70
71 - def __repr__(self):
72 return '<%s %s>' % (self.__class__.__name__, self.uri)
73
74 - def _set_default_attrs(self, obj):
75 for attr_name in ('charset', 'encode_keys', 'pool_class', 76 'keepalive', 'basic_auth_url'): 77 setattr(obj, attr_name, getattr(self, attr_name)) 78 return obj
79
80 - def clone(self):
81 """if you want to add a path to resource uri, you can do: 82 83 .. code-block:: python 84 85 resr2 = res.clone() 86 87 """ 88 obj = self.__class__(self.uri, headers=self._headers, 89 **self.client_opts) 90 return self._set_default_attrs(obj)
91
92 - def __call__(self, path):
93 """if you want to add a path to resource uri, you can do: 94 95 .. code-block:: python 96 97 Resource("/path").get() 98 """ 99 100 new_uri = util.make_uri(self.uri, path, charset=self.charset, 101 safe=self.safe, encode_keys=self.encode_keys) 102 103 obj = type(self)(new_uri, headers=self._headers, **self.client_opts) 104 return self._set_default_attrs(obj)
105
106 - def get(self, path=None, headers=None, **params):
107 """ HTTP GET 108 109 :param path: string additionnal path to the uri 110 :param headers: dict, optionnal headers that will 111 be added to HTTP request. 112 :param params: Optionnal parameterss added to the request. 113 """ 114 return self.request("GET", path=path, headers=headers, **params)
115
116 - def head(self, path=None, headers=None, **params):
117 """ HTTP HEAD 118 119 see GET for params description. 120 """ 121 return self.request("HEAD", path=path, headers=headers, **params)
122
123 - def delete(self, path=None, headers=None, **params):
124 """ HTTP DELETE 125 126 see GET for params description. 127 """ 128 return self.request("DELETE", path=path, headers=headers, **params)
129
130 - def post(self, path=None, payload=None, headers=None, **params):
131 """ HTTP POST 132 133 :param payload: string passed to the body of the request 134 :param path: string additionnal path to the uri 135 :param headers: dict, optionnal headers that will 136 be added to HTTP request. 137 :param params: Optionnal parameterss added to the request 138 """ 139 140 return self.request("POST", path=path, payload=payload, 141 headers=headers, **params)
142
143 - def put(self, path=None, payload=None, headers=None, **params):
144 """ HTTP PUT 145 146 see POST for params description. 147 """ 148 return self.request("PUT", path=path, payload=payload, 149 headers=headers, **params)
150
151 - def do_request(self, url, method='GET', payload=None, headers=None):
152 http_client = HttpConnection(**self.client_opts) 153 return http_client.request(url, method=method, body=payload, 154 headers=headers)
155
156 - def request(self, method, path=None, payload=None, headers=None, 157 **params):
158 """ HTTP request 159 160 This method may be the only one you want to override when 161 subclassing `restkit.rest.Resource`. 162 163 :param payload: string or File object passed to the body of the request 164 :param path: string additionnal path to the uri 165 :param headers: dict, optionnal headers that will 166 be added to HTTP request. 167 :param params: Optionnal parameterss added to the request 168 """ 169 170 headers = headers or [] 171 uri = util.make_uri(self.uri, path, charset=self.charset, 172 safe=self.safe, encode_keys=self.encode_keys, 173 **params) 174 175 try: 176 resp = self.do_request(uri, method=method, payload=payload, 177 headers=headers) 178 except ParserError: 179 raise 180 except Exception, e: 181 raise RequestError(e) 182 183 if resp is None: 184 # race condition 185 raise RequestError("unkown error") 186 187 if resp.status_int >= 400: 188 if resp.status_int == 404: 189 raise ResourceNotFound(resp.body_string(), http_code=404, response=resp) 190 elif resp.status_int in (401, 403): 191 raise Unauthorized(resp.body_string(), http_code=resp.status_int, 192 response=resp) 193 else: 194 raise RequestFailed(resp.body_string(), http_code=resp.status_int, 195 response=resp) 196 197 return resp
198
199 - def update_uri(self, path):
200 """ 201 to set a new uri absolute path 202 """ 203 self.uri = util.make_uri(self.uri, path, charset=self.charset, 204 safe=self.safe, encode_keys=self.encode_keys)
205