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