b1935e5bd034f1789a4516bda7ab6fcca2389003
[kamaki] / kamaki / clients / connection / __init__.py
1 # Copyright 2011-2012 GRNET S.A. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or
4 # without modification, are permitted provided that the following
5 # conditions are met:
6 #
7 #   1. Redistributions of source code must retain the above
8 #      copyright notice, self.list of conditions and the following
9 #      disclaimer.
10 #
11 #   2. Redistributions in binary form must reproduce the above
12 #      copyright notice, self.list of conditions and the following
13 #      disclaimer in the documentation and/or other materials
14 #      provided with the distribution.
15 #
16 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
28 #
29 # The views and conclusions contained in the software and
30 # documentation are those of the authors and should not be
31 # interpreted as representing official policies, either expressed
32 # or implied, of GRNET S.A.
33
34
35 class HTTPResponse(object):
36     """An abstract HTTP Response object to handle a performed HTTPRequest.
37     Subclass implementation required
38     """
39
40     def __init__(self, request=None, prefetched=False):
41         self.request = request
42         self.prefetched = prefetched
43
44     def _get_response(self):
45         """Wait for http response as late as possible: the first time needed"""
46         if self.prefetched:
47             return
48         self = self.request.response
49         self.prefetched = True
50
51     def release(self):
52         """Release the connection.
53         """
54         raise NotImplementedError
55
56     @property
57     def prefetched(self):
58         """flag to avoid downloading more than nessecary"""
59         return self._prefetched
60
61     @prefetched.setter
62     def prefetched(self, p):
63         self._prefetched = p
64
65     @property
66     def content(self):
67         """(binary) request response content (data)"""
68         self._get_response()
69         return self._content
70
71     @content.setter
72     def content(self, v):
73         self._content = v
74
75     @property
76     def text(self):
77         """(str)"""
78         self._get_response()
79         return self._text
80
81     @text.setter
82     def text(self, v):
83         self._text = v
84
85     @property
86     def json(self):
87         """(dict)"""
88         self._get_response()
89         return self._json
90
91     @json.setter
92     def json(self, v):
93         self._json = v
94
95     @property
96     def headers(self):
97         """(dict)"""
98         self._get_response()
99         return self._headers
100
101     @headers.setter
102     def headers(self, v):
103         self._headers = v
104
105     @property
106     def status_code(self):
107         """(int) optional"""
108         self._get_response()
109         return self._status_code
110
111     @status_code.setter
112     def status_code(self, v):
113         self._status_code = v
114
115     @property
116     def status(self):
117         """(str) useful in server error responses"""
118         self._get_response()
119         return self._status
120
121     @status.setter
122     def status(self, v):
123         self._status = v
124
125     @property
126     def request(self):
127         """(HTTPConnection) the source of this response object"""
128         return self._request
129
130     @request.setter
131     def request(self, v):
132         self._request = v
133
134
135 class HTTPConnection(object):
136     """An abstract HTTP Connection mechanism. Subclass implementation required
137     """
138
139     def __init__(self, method=None, url=None, params={}, headers={}):
140         self.headers = headers
141         self.params = params
142         self.url = url
143         self.path = ''
144         self.method = method
145
146     def set_header(self, name, value):
147         self.headers['%s' % name] = '%s' % value
148
149     def remove_header(self, name):
150         try:
151             self.headers.pop(name)
152         except KeyError:
153             pass
154
155     def replace_headers(self, new_headers):
156         self.headers = new_headers
157
158     def reset_headers(self):
159         self.replace_headers({})
160
161     def set_param(self, name, value=None):
162         self.params[name] = value
163
164     def remove_param(self, name):
165         try:
166             self.params.pop(name)
167         except KeyError:
168             pass
169
170     def replace_params(self, new_params):
171         self.params = new_params
172
173     def reset_params(self):
174         self.replace_params({})
175
176     def set_url(self, url):
177         self.url = url
178
179     def set_path(self, path):
180         self.path = path
181
182     def set_method(self, method):
183         self.method = method
184
185     def perform_request(
186             self,
187             method=None,
188             url=None,
189             async_headers={},
190             async_params={},
191             data=None):
192         raise NotImplementedError