This repository was archived by the owner on Aug 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathresource.py
More file actions
149 lines (122 loc) · 4.68 KB
/
resource.py
File metadata and controls
149 lines (122 loc) · 4.68 KB
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
import json
import copy
import requests
try:
from requests_futures.sessions import FuturesSession
requests_futures_available = True
except ImportError:
requests_futures_available = False
try:
import urllib.parse as urlparse
except ImportError:
import urlparse
class RequestsFutureNotAvailable(Exception):
message = "Please install request_sessions before proceeding."
class Resource(object):
"""
REST resource class: implements GET, POST, PUT, DELETE methods
for all other Divan objects, and manages settings inheritance.
If you create an object, like an `Account`, then use that to
create a `Database` object, the `Database` will inherit any options
from the `Account` object, such as session cookies.
Implements CRUD operations for all other Cloudant-Python objects.
"""
def __init__(self, uri, **kwargs):
self.uri = uri
self.uri_parts = urlparse.urlparse(self.uri)
if kwargs.get('session'):
self._session = kwargs['session']
del kwargs['session']
elif 'async' in kwargs:
if kwargs['async']:
if not requests_futures_available:
raise RequestsFutureNotAvailable()
self._session = FuturesSession()
else:
self._session = requests.Session()
del kwargs['async']
else:
self._session = requests.Session()
self._set_options(**kwargs)
def _set_options(self, **kwargs):
if not hasattr(self, 'opts'):
self.opts = {
'headers': {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
if kwargs:
self.opts.update(kwargs)
def _make_url(self, path=''):
"""Joins the uri, and optional path"""
if path:
# if given a full URL, use that instead
if urlparse.urlparse(path).scheme:
return path
else:
return urlparse.urljoin(self.uri, path)
else:
return self.uri
def _reset_path(self, path):
parts = list(self.uri_parts)
parts[2] = path
url = urlparse.urlunparse(parts)
return url
def _make_request(self, method, path='', **kwargs):
# kwargs supercede self.opts
opts = copy.copy(self.opts)
opts.update(kwargs)
# normalize `params` kwarg according to method
if 'params' in opts:
if method in ['post', 'put'] and 'data' not in opts:
opts['data'] = json.dumps(opts['params'])
del opts['params']
else:
# cloudant breaks on True and False, so lowercase it
params = opts['params']
for key, value in params.items():
if value in [True, False]:
params[key] = str(value).lower()
elif type(value) in [list, dict, tuple]:
params[key] = json.dumps(value)
opts['params'] = params
# make the request
future = getattr(self._session, method)(self._make_url(path), **opts)
return future
def head(self, path='', **kwargs):
"""
Make a HEAD request against the object's URI joined
with `path`. `kwargs` are passed directly to Requests.
"""
return self._make_request('head', path, **kwargs)
def get(self, path='', **kwargs):
"""
Make a GET request against the object's URI joined
with `path`. `kwargs` are passed directly to Requests.
"""
return self._make_request('get', path, **kwargs)
def put(self, path='', **kwargs):
"""
Make a PUT request against the object's URI joined
with `path`.
`kwargs['params']` are turned into JSON before being
passed to Requests. If you want to indicate the message
body without it being modified, use `kwargs['data']`.
"""
return self._make_request('put', path, **kwargs)
def post(self, path='', **kwargs):
"""
Make a POST request against the object's URI joined
with `path`.
`kwargs['params']` are turned into JSON before being
passed to Requests. If you want to indicate the message
body without it being modified, use `kwargs['data']`.
"""
return self._make_request('post', path, **kwargs)
def delete(self, path='', **kwargs):
"""
Make a DELETE request against the object's URI joined
with `path`. `kwargs` are passed directly to Requests.
"""
return self._make_request('delete', path, **kwargs)