Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / __init__.py @ d1856abf

History | View | Annotate | Download (5.2 kB)

1 43ca98ee Giorgos Verigakis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 a1c50326 Giorgos Verigakis
#
3 a1c50326 Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
4 a1c50326 Giorgos Verigakis
# without modification, are permitted provided that the following
5 a1c50326 Giorgos Verigakis
# conditions are met:
6 a1c50326 Giorgos Verigakis
#
7 a1c50326 Giorgos Verigakis
#   1. Redistributions of source code must retain the above
8 e742badc Stavros Sachtouris
#      copyright notice, self.list of conditions and the following
9 a1c50326 Giorgos Verigakis
#      disclaimer.
10 a1c50326 Giorgos Verigakis
#
11 a1c50326 Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
12 e742badc Stavros Sachtouris
#      copyright notice, self.list of conditions and the following
13 a1c50326 Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
14 a1c50326 Giorgos Verigakis
#      provided with the distribution.
15 a1c50326 Giorgos Verigakis
#
16 a1c50326 Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 a1c50326 Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 a1c50326 Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 a1c50326 Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 a1c50326 Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 a1c50326 Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 a1c50326 Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 a1c50326 Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 a1c50326 Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 a1c50326 Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 a1c50326 Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 a1c50326 Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
28 a1c50326 Giorgos Verigakis
#
29 a1c50326 Giorgos Verigakis
# The views and conclusions contained in the software and
30 a1c50326 Giorgos Verigakis
# documentation are those of the authors and should not be
31 a1c50326 Giorgos Verigakis
# interpreted as representing official policies, either expressed
32 a1c50326 Giorgos Verigakis
# or implied, of GRNET S.A.
33 a1c50326 Giorgos Verigakis
34 6a0b1658 Giorgos Verigakis
import json
35 6a0b1658 Giorgos Verigakis
import logging
36 6a0b1658 Giorgos Verigakis
37 6a0b1658 Giorgos Verigakis
import requests
38 6a0b1658 Giorgos Verigakis
39 6a0b1658 Giorgos Verigakis
from requests.auth import AuthBase
40 6a0b1658 Giorgos Verigakis
41 6a0b1658 Giorgos Verigakis
42 6a0b1658 Giorgos Verigakis
sendlog = logging.getLogger('clients.send')
43 6a0b1658 Giorgos Verigakis
recvlog = logging.getLogger('clients.recv')
44 6a0b1658 Giorgos Verigakis
45 6a0b1658 Giorgos Verigakis
46 6a0b1658 Giorgos Verigakis
# Add a convenience status property to the responses
47 6a0b1658 Giorgos Verigakis
def _status(self):
48 6a0b1658 Giorgos Verigakis
    return requests.status_codes._codes[self.status_code][0].upper()
49 6a0b1658 Giorgos Verigakis
requests.Response.status = property(_status)
50 6a0b1658 Giorgos Verigakis
51 6a0b1658 Giorgos Verigakis
52 a1c50326 Giorgos Verigakis
class ClientError(Exception):
53 a1c50326 Giorgos Verigakis
    def __init__(self, message, status=0, details=''):
54 59dec327 Giorgos Verigakis
        super(ClientError, self).__init__(message, status, details)
55 a1c50326 Giorgos Verigakis
        self.message = message
56 a1c50326 Giorgos Verigakis
        self.status = status
57 a1c50326 Giorgos Verigakis
        self.details = details
58 a1c50326 Giorgos Verigakis
59 a1c50326 Giorgos Verigakis
60 6a0b1658 Giorgos Verigakis
class Client(object):
61 43ca98ee Giorgos Verigakis
    def __init__(self, base_url, token):
62 6a0b1658 Giorgos Verigakis
        self.base_url = base_url
63 6c62a96d Giorgos Verigakis
        self.token = token
64 e742badc Stavros Sachtouris
        self.headers = {}
65 6c62a96d Giorgos Verigakis
66 44b8928d Giorgos Verigakis
    def raise_for_status(self, r):
67 43ca98ee Giorgos Verigakis
        message = "%d %s" % (r.status_code, r.status)
68 43ca98ee Giorgos Verigakis
        details = r.text
69 6a0b1658 Giorgos Verigakis
        raise ClientError(message, r.status_code, details)
70 6a0b1658 Giorgos Verigakis
71 e742badc Stavros Sachtouris
    def set_header(self, name, value):
72 e742badc Stavros Sachtouris
        #If the header exists, replace the value
73 e742badc Stavros Sachtouris
        #otherwise create a new header
74 e742badc Stavros Sachtouris
        self.headers[unicode(name)] = unicode(value)
75 e742badc Stavros Sachtouris
76 6a0b1658 Giorgos Verigakis
    def request(self, method, path, **kwargs):
77 6a0b1658 Giorgos Verigakis
        raw = kwargs.pop('raw', False)
78 6a0b1658 Giorgos Verigakis
        success = kwargs.pop('success', 200)
79 f3a722d4 Stavros Sachtouris
        directory = kwargs.pop('directory', False)
80 e742badc Stavros Sachtouris
        #meta = kwargs.pop('meta', False)
81 6c62a96d Giorgos Verigakis
82 6c62a96d Giorgos Verigakis
        data = kwargs.pop('data', None)
83 e742badc Stavros Sachtouris
        #headers = kwargs.pop('headers', {})
84 e742badc Stavros Sachtouris
        self.headers.setdefault('X-Auth-Token', self.token)
85 87688514 Stavros Sachtouris
        publish = kwargs.pop('publish', None)
86 6c62a96d Giorgos Verigakis
87 f3a722d4 Stavros Sachtouris
        if directory:
88 e742badc Stavros Sachtouris
            self.headers.setdefault('Content-Type', 'application/directory')
89 e742badc Stavros Sachtouris
            self.headers.setdefault('Content-length', '0')
90 f3a722d4 Stavros Sachtouris
        else:
91 f3a722d4 Stavros Sachtouris
            if 'json' in kwargs:
92 f3a722d4 Stavros Sachtouris
                data = json.dumps(kwargs.pop('json'))
93 e742badc Stavros Sachtouris
                self.headers.setdefault('Content-Type', 'application/json')
94 f3a722d4 Stavros Sachtouris
            if data:
95 e742badc Stavros Sachtouris
                self.headers.setdefault('Content-Length', unicode(len(data)))
96 6a0b1658 Giorgos Verigakis
97 e742badc Stavros Sachtouris
        #if meta:
98 e742badc Stavros Sachtouris
        #    for key in meta.keys():
99 e742badc Stavros Sachtouris
        #        self.headers[key] = meta[key]
100 87688514 Stavros Sachtouris
101 6a0b1658 Giorgos Verigakis
        url = self.base_url + path
102 be4f79ea Giorgos Verigakis
        kwargs.setdefault('verify', False)  # Disable certificate verification
103 e742badc Stavros Sachtouris
        r = requests.request(method, url, headers=self.headers, data=data, **kwargs)
104 6c62a96d Giorgos Verigakis
105 6a0b1658 Giorgos Verigakis
        req = r.request
106 6a0b1658 Giorgos Verigakis
        sendlog.info('%s %s', req.method, req.url)
107 6a0b1658 Giorgos Verigakis
        for key, val in req.headers.items():
108 6a0b1658 Giorgos Verigakis
            sendlog.info('%s: %s', key, val)
109 6a0b1658 Giorgos Verigakis
        sendlog.info('')
110 6a0b1658 Giorgos Verigakis
        if req.data:
111 6a0b1658 Giorgos Verigakis
            sendlog.info('%s', req.data)
112 44b8928d Giorgos Verigakis
113 6a0b1658 Giorgos Verigakis
        recvlog.info('%d %s', r.status_code, r.status)
114 6a0b1658 Giorgos Verigakis
        for key, val in r.headers.items():
115 6a0b1658 Giorgos Verigakis
            recvlog.info('%s: %s', key, val)
116 6a0b1658 Giorgos Verigakis
        recvlog.info('')
117 72462fc2 Giorgos Verigakis
        if not raw and r.content:
118 72462fc2 Giorgos Verigakis
            recvlog.debug(r.content)
119 44b8928d Giorgos Verigakis
120 6a0b1658 Giorgos Verigakis
        if success is not None:
121 6a0b1658 Giorgos Verigakis
            # Success can either be an in or a collection
122 6a0b1658 Giorgos Verigakis
            success = (success,) if isinstance(success, int) else success
123 6a0b1658 Giorgos Verigakis
            if r.status_code not in success:
124 6a0b1658 Giorgos Verigakis
                self.raise_for_status(r)
125 6a0b1658 Giorgos Verigakis
126 a1c50326 Giorgos Verigakis
        return r
127 a1c50326 Giorgos Verigakis
128 6a0b1658 Giorgos Verigakis
    def delete(self, path, **kwargs):
129 6a0b1658 Giorgos Verigakis
        return self.request('delete', path, **kwargs)
130 6a0b1658 Giorgos Verigakis
131 6a0b1658 Giorgos Verigakis
    def get(self, path, **kwargs):
132 6a0b1658 Giorgos Verigakis
        return self.request('get', path, **kwargs)
133 6a0b1658 Giorgos Verigakis
134 6a0b1658 Giorgos Verigakis
    def head(self, path, **kwargs):
135 6a0b1658 Giorgos Verigakis
        return self.request('head', path, **kwargs)
136 6a0b1658 Giorgos Verigakis
137 6a0b1658 Giorgos Verigakis
    def post(self, path, **kwargs):
138 6a0b1658 Giorgos Verigakis
        return self.request('post', path, **kwargs)
139 6a0b1658 Giorgos Verigakis
140 6a0b1658 Giorgos Verigakis
    def put(self, path, **kwargs):
141 6a0b1658 Giorgos Verigakis
        return self.request('put', path, **kwargs)
142 6a0b1658 Giorgos Verigakis
143 a1c50326 Giorgos Verigakis
144 6a0b1658 Giorgos Verigakis
from .compute import ComputeClient as compute
145 6a0b1658 Giorgos Verigakis
from .image import ImageClient as image
146 6a0b1658 Giorgos Verigakis
from .storage import StorageClient as storage
147 6a0b1658 Giorgos Verigakis
from .cyclades import CycladesClient as cyclades
148 6a0b1658 Giorgos Verigakis
from .pithos import PithosClient as pithos
149 43ca98ee Giorgos Verigakis
from .astakos import AstakosClient as astakos