GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 40fbfa...d5d9b4 )
by Daniel
51s
created

DatabaseConnection.ping()   A

Complexity

Conditions 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 1
c 3
b 0
f 0
dl 0
loc 5
rs 9.4285
1
from __future__ import absolute_import
2
3
# python 3 vs 2
4
try:
5
    from urlparse import urljoin
6
except:
7
    from urllib.parse import urljoin
8
9
from requests import Session
10
from requests.auth import HTTPBasicAuth
11
12
import json
13
14
from ._websocket import WebsocketHandler
15
16
# The subpath to the Create Read Update Delete portion of the API
17
CRUD_PATH = "crud/"
18
19
20
# Returned when the given credentials are not accepted by the server
21
class AuthenticationError(Exception):
22
23
    def __init__(self, value):
24
        self.value = value
25
26
    def __str__(self):
27
        return repr(self.value)
28
29
30
# Returned when the server gives an unhandled error code
31
class ServerError(Exception):
32
33
    def __init__(self, value):
34
        self.value = value
35
36
    def __str__(self):
37
        return repr(self.value)
38
39
40
class DatabaseConnection(object):
41
42
    def __init__(self, user_or_apikey=None, user_password=None, url="https://connectordb.com"):
43
44
        # Set up the API URL
45
        if not url.startswith("http"):
46
            url = "https://" + url
47
        if not url.endswith("/"):
48
            url = url + "/"
49
        self.baseurl = url
50
        self.url = urljoin(url, "/api/v1/")
51
52
        # Set up a session, which allows us to reuse connections
53
        self.r = Session()
54
        self.r.headers.update({'content-type': 'application/json'})
55
56
        # Prepare the websocket
57
        self.ws = WebsocketHandler(self.url, None)
58
59
        # Set the authentication if any
60
        self.setauth(user_or_apikey, user_password)
61
62
        # Now set up the login path so we know what we're logged in as
63
        if user_password is not None:
64
            self.path = user_or_apikey + "/user"
65
        else:
66
            self.path = self.ping()
67
68
    def setauth(self, user_or_apikey=None, user_password=None):
69
        """ setauth sets the authentication header for use in the session.
70
        It is for use when apikey is updated or something of the sort, such that
71
        there is a seamless experience. """
72
        auth = None
73
        if user_or_apikey is not None:
74
            # ConnectorDB allows login using both basic auth or an apikey url param.
75
            # The python client uses basic auth for all logins
76
            if user_password is None:
77
                # Login by api key - the basic auth login uses "" user and
78
                # apikey as password
79
                user_password = user_or_apikey
80
                user_or_apikey = ""
81
            auth = HTTPBasicAuth(user_or_apikey, user_password)
82
            self.r.auth = auth
83
84
        # Set the websocket's authentication
85
        self.ws.setauth(auth)
86
87
    def close(self):
88
        """Closes the active connections to ConnectorDB"""
89
        self.r.close()
90
91
    def handleresult(self, r):
92
        """Handles HTTP error codes for the given request
93
94
        Raises:
95
            AuthenticationError on the appropriate 4** errors
96
            ServerError if the response is not an ok (2**)
97
98
        Arguments:
99
            r -- The request result
100
        """
101
        if r.status_code >= 400 and r.status_code < 500:
102
            msg = r.json()
103
            raise AuthenticationError(str(msg["code"]) + ": " + msg["msg"] +
104
                                      " (" + msg["ref"] + ")")
105
        elif r.status_code > 300:
106
            err = None
107
            try:
108
                msg = r.json()
109
                err = ServerError(str(msg["code"]) + ": " + msg["msg"] + " (" +
110
                                  msg["ref"] + ")")
111
            except:
112
                raise ServerError(
113
                    "Server returned error, but did not give a valid error message")
114
            raise err
115
        return r
116
117
    def ping(self):
118
        """Attempts to ping the server using current credentials, and responds with the path of the currently
119
        authenticated device"""
120
        return self.handleresult(self.r.get(self.url,
121
                                            params={"q": "this"})).text
122
123
    def query(self, query_type, query=None):
124
        """Run the given query on the connection (POST request to /query)"""
125
        return self.handleresult(self.r.post(urljoin(self.url + "query/",
126
                                                     query_type),
127
                                             data=json.dumps(query))).json()
128
129
    def create(self, path, data=None):
130
        """Send a POST CRUD API request to the given path using the given data which will be converted
131
        to json"""
132
        return self.handleresult(self.r.post(urljoin(self.url + CRUD_PATH,
133
                                                     path),
134
                                             data=json.dumps(data)))
135
136
    def read(self, path, params=None):
137
        """Read the result at the given path (GET) from the CRUD API, using the optional params dictionary
138
        as url parameters."""
139
        return self.handleresult(self.r.get(urljoin(self.url + CRUD_PATH,
140
                                                    path),
141
                                            params=params))
142
143
    def update(self, path, data=None):
144
        """Send an update request to the given path of the CRUD API, with the given data dict, which will be converted
145
        into json"""
146
        return self.handleresult(self.r.put(urljoin(self.url + CRUD_PATH,
147
                                                    path),
148
                                            data=json.dumps(data)))
149
150
    def delete(self, path):
151
        """Send a delete request to the given path of the CRUD API. This deletes the object. Or at least tries to."""
152
        return self.handleresult(self.r.delete(urljoin(self.url + CRUD_PATH,
153
                                                       path)))
154
155
    def get(self, path, params=None):
156
        """Sends a get request to the given path in the database and with optional URL parameters"""
157
        return self.handleresult(self.r.get(urljoin(self.url, path),
158
                                            params=params))
159
160
    def subscribe(self, stream, callback, transform=""):
161
        """Subscribe to the given stream with the callback"""
162
        return self.ws.subscribe(stream, callback, transform)
163
164
    def unsubscribe(self, stream, transform=""):
165
        """Unsubscribe from the given stream"""
166
        return self.ws.unsubscribe(stream, transform)
167
168
    def wsdisconnect(self):
169
        """Disconnects the websocket"""
170
        self.ws.disconnect()
171