-
Notifications
You must be signed in to change notification settings - Fork 1
/
application.py
152 lines (114 loc) · 4.15 KB
/
application.py
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
150
151
152
from blizzard import BlizzardTools
from flask import Flask
from flask import jsonify
from flask import request
from flask_basicauth import BasicAuth
from requests.exceptions import HTTPError
from os import environ
from logging.config import dictConfig
logging_level = environ['LOG_LEVEL']
dictConfig({
'version': 1,
'formatters': {'default': {
'format': 'timestamp=%(asctime)s,level=%(levelname)s,message="%(message)s"',
'datefmt': '%Y-%m-%dT%H:%M:%S'
}},
'handlers': {'wsgi': {
'class': 'logging.StreamHandler',
'stream': 'ext://flask.logging.wsgi_errors_stream',
'formatter': 'default'
}},
'root': {
'level': logging_level,
'handlers': ['wsgi']
}
})
application = Flask(__name__)
application.config['BASIC_AUTH_USERNAME'] = environ['BASIC_AUTH_USERNAME']
application.config['BASIC_AUTH_PASSWORD'] = environ['BASIC_AUTH_PASSWORD']
basic_auth = BasicAuth(application)
auth_data = {"client_id": environ.get("CLIENT_ID"),
"client_secret": environ.get("CLIENT_SECRET")}
blizzardtools = BlizzardTools(auth_data)
# Custom Exceptions to return contextual HTTP error codes.
class GenericAPIError(Exception):
status_code = 500
def __init__(self, message, status_code=None, payload=None):
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
class ResourceNotFound(Exception):
status_code = 404
def __init__(self, message, status_code=None, payload=None):
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
class RequestFailed(Exception):
status_code = 503
def __init__(self, message, status_code=None, payload=None):
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
class UnauthorizedRequest(Exception):
status_code = 401
def __init__(self, message, status_code=None, payload=None):
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
@application.route('/')
def go_away():
application.logger.info(f'{request.remote_addr} requested {request.url}')
response = {"status": "OK",
"message": "Nothing to see here"}
return jsonify(response)
@application.route('/rostermanager/<realm>/<guild>')
@basic_auth.required
def rostermanager(realm, guild):
application.logger.info(f'{request.remote_addr} requested {request.url}')
try:
response = blizzardtools.get_raiders(realm, guild)
application.logger.info(f'fetched guild member data for {guild}_{realm},{len(response)} records found')
return jsonify(response)
except HTTPError as e:
application.logger.error(f'failed fetching upstream data, {e}')
raise GenericAPIError('Failed fetching upstream data')
@application.errorhandler(GenericAPIError)
def handle_generic_api_error(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
@application.errorhandler(ResourceNotFound)
def handle_resource_not_found(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
@application.errorhandler(RequestFailed)
def handle_request_failed(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
@application.errorhandler(UnauthorizedRequest)
def handle_unauthorized_request(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response