1
2
3
4
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
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
53 u = urlparse.urlparse(uri)
54 if u.username:
55 password = u.password or ""
56
57
58 filters = client_opts.get('filters', [])
59 filters.append(BasicAuth(u.username, password))
60 client_opts['filters'] = filters
61
62
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
72 return '<%s %s>' % (self.__class__.__name__, self.uri)
73
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
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
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):
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
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
205