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.

Issues (51)

besepa/api.py (2 issues)

1
import datetime
2
import json
3
import logging
4
import os
5
import platform
6
import ssl
7
8
import requests
9
10
import besepa.util as util
11
from besepa import exceptions
12
from besepa.config import __endpoint_map__, __version__
13
14
log = logging.getLogger(__name__)
0 ignored issues
show
Coding Style Naming introduced by
The name log does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
15
16
17
class Api(object):
18
    # User-Agent for HTTP request
19
    ssl_version = ssl.OPENSSL_VERSION
20
    library_details = "requests %s; python %s; %s" % (requests.__version__, platform.python_version(), ssl_version)
21
    user_agent = "BesepaSDK/Besepa-Python-SDK %s (%s)" % (__version__, library_details)
22
23
    def __init__(self, options=None, **kwargs):
24
        """Create API object
25
26
        Usage::
27
28
            >>> import besepa
29
            >>> api = besepa.Api(mode="sandbox", api_key='API_KEY')
30
        """
31
        kwargs = util.merge_dict(options or {}, kwargs)
32
33
        self.mode = kwargs.get("mode", "sandbox")
34
35
        if self.mode not in ("live", "sandbox"):
36
            raise exceptions.InvalidConfig("Configuration Mode Invalid", "Received: %s" % self.mode,
37
                                           "Required: live or sandbox")
38
39
        self.endpoint = self.default_endpoint()
40
        # Mandatory parameter, so not using `dict.get`
41
        self.api_key = kwargs["api_key"]
42
        self.proxies = kwargs.get("proxies", None)
43
44
        self.options = kwargs
45
46
    def default_endpoint(self):
47
        return __endpoint_map__.get(self.mode)
48
49
    def request(self, url, method, body=None, headers=None):
50
        """Make HTTP call, formats response and does error handling. Uses http_call method in API class.
51
52
        Usage::
53
54
            >>> api.request("https://sandbox.besepa.com/api/1/customers", "GET", {})
55
            >>> api.request("https://sandbox.besepa.com/api/1/customers", "POST",
56
             "{'name': 'Ender Wiggin', 'taxid': '68571053A', 'reference: C1'}", {} )
57
        """
58
        http_headers = util.merge_dict(self.headers(), headers or {})
59
60
        try:
61
            return self.http_call(url, method, json=body, headers=http_headers)
62
        # Format Error message for bad request
63
        except exceptions.BadRequest as error:
64
            return {"error": json.loads(error.content)}
65
66
    def http_call(self, url, method, **kwargs):
67
        """Makes a http call. Logs response information.
68
        """
69
        log.info('Request[%s]: %s' % (method, url))
70
71
        if self.mode.lower() != 'live':
72
            request_headers = kwargs.get("headers", {})
73
            request_body = kwargs.get("json", {})
74
            log.debug("Level: " + self.mode)
75
            log.debug('Request: \nHeaders: %s\nBody: %s' % (str(request_headers), str(request_body)))
76
        else:  # pragma: no cover
77
            log.info('Not logging full request/response headers and body in live mode for compliance')
78
79
        start_time = datetime.datetime.now()
80
        response = requests.request(method, url, proxies=self.proxies, **kwargs)
81
        duration = datetime.datetime.now() - start_time
82
        log.info('Response[%d]: %s, Duration: %s.%ss.' % (
83
            response.status_code, response.reason, duration.seconds, duration.microseconds))
84
85
        debug_id = response.headers.get('Besepa-Debug-Id')
86
        if debug_id:  # pragma: no cover
87
            log.debug('debug_id: %s' % debug_id)
88
        if self.mode.lower() != 'live':  # pragma: no cover
89
            log.debug('Headers: %s\nBody: %s' % (str(response.headers), response.content.decode('utf-8')))
90
91
        return self.handle_response(response, response.content.decode('utf-8'))
92
93
    @staticmethod
94
    def handle_response(response, content):
95
        """Validate HTTP response
96
        """
97
        status = response.status_code
98
        if status in (301, 302, 303, 307):
99
            raise exceptions.Redirection(response, content)
100
        elif 200 <= status <= 299:
101
            return json.loads(content).get('response') if content else {}
102
        elif status == 400:
103
            raise exceptions.BadRequest(response, content)
104
        elif status == 401:
105
            raise exceptions.UnauthorizedAccess(response, content)
106
        elif status == 403:
107
            raise exceptions.ForbiddenAccess(response, content)
108
        elif status == 404:
109
            raise exceptions.ResourceNotFound(response, content)
110
        elif status == 405:
111
            raise exceptions.MethodNotAllowed(response, content)
112
        elif status == 409:
113
            raise exceptions.ResourceConflict(response, content)
114
        elif status == 410:
115
            raise exceptions.ResourceGone(response, content)
116
        elif status == 422:
117
            raise exceptions.ResourceInvalid(response, content)
118
        elif 401 <= status <= 499:
119
            raise exceptions.ClientError(response, content)
120
        elif 500 <= status <= 599:
121
            raise exceptions.ServerError(response, content)
122
        else:
123
            raise exceptions.ConnectionError(response, content, "Unknown response code: #{response.code}")
124
125
    def headers(self):
126
        """Default HTTP headers
127
        """
128
        return {
129
            "Authorization": ("Bearer %s" % self.api_key),
130
            "Content-Type": "application/json",
131
            "Accept": "application/json",
132
            "User-Agent": self.user_agent
133
        }
134
135
    def get(self, action, headers=None):
136
        """Make GET request
137
138
        Usage::
139
140
            >>> api.get("api/1/customers")
141
            >>> api.get("api/1/customers/1")
142
        """
143
        return self.request(util.join_url(self.endpoint, action), 'GET', headers=headers or {})
144
145
    def post(self, action, params=None, headers=None):
146
        """Make POST request
147
148
        Usage::
149
150
            >>> api.post("api/1/customers", {'name': 'Ender Wiggin', 'taxid': '68571053A', 'reference: C1'})
151
        """
152
        return self.request(util.join_url(self.endpoint, action), 'POST', body=params or {}, headers=headers or {})
153
154
    def patch(self, action, params=None, headers=None):
155
        """Make PATCH request
156
157
        Usage::
158
159
            >>> api.patch("api/1/customers/1", {'name': 'Andrew Wiggins'})
160
        """
161
        return self.request(util.join_url(self.endpoint, action), 'PATCH', body=params or {}, headers=headers or {})
162
163
    def delete(self, action, headers=None):
164
        """Make DELETE request
165
        """
166
        return self.request(util.join_url(self.endpoint, action), 'DELETE', headers=headers or {})
167
168
169
__api__ = None
170
171
172
def default():
173
    """Returns default api object and if not present creates a new one
174
    By default points to developer sandbox
175
    """
176
    global __api__
177
    if __api__ is None:
178
        try:
179
            api_key = os.environ["BESEPA_API_KEY"]
180
        except KeyError:
181
            raise exceptions.MissingConfig("Required BESEPA_API_KEY. \
182
                Refer http://docs.besepaen.apiary.io/#introduction/authorization")
183
184
        __api__ = Api(mode=os.environ.get("BESEPA_MODE", "sandbox"), api_key=api_key)
185
    return __api__
186
187
188
def set_config(options=None, **config):
189
    """Create new default api object with given configuration
190
    """
191
    global __api__
192
    __api__ = Api(options or {}, **config)
193
    return __api__
194
195
196
configure = set_config
0 ignored issues
show
Coding Style Naming introduced by
The name configure does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
197