Completed
Push — master ( 17ec8d...3c3c2c )
by Chris
01:14
created

custom_inputs()   A

Complexity

Conditions 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
c 0
b 0
f 0
dl 0
loc 8
rs 9.4285
1
"""A separate Flask app that serves fake endpoints for demo purposes."""
2
3
# -*- coding: utf-8 -*-
4
5
import json
6
import locale
7
import os
8
from datetime import timedelta as td
9
from datetime import datetime as dt
10
from random import randrange as rr
11
from random import choice, random
12
import time
13
14
from flask import (
15
    Flask,
16
    abort,
17
    request,
18
    render_template,
19
)
20
from flask.ext.cors import CORS
21
from flask.ext.cors import cross_origin
22
23
app = Flask('endpoints_test')
24
CORS(app)
25
app.config['SECRET_KEY'] = 'NOTSECURELOL'
26
app.debug = True
27
28
STRESS_MAX_POINTS = 300
29
30
locale.setlocale(locale.LC_ALL, '')
31
32
cwd = os.getcwd()
33
34
35
def recursive_d3_data(current=0, max_iters=12, data=None):
36
    """Generate d3js data for stress testing.
37
    Format is suitable in treemap, circlepack and dendrogram testing.
38
    """
39
    if current >= max_iters:
40
        return data
41
    if data is None:
42
        data = dict(name='foo', size=rr(10, 10000), children=[])
43
    data = dict(name='foo', size=rr(10, 10000),
44
                children=[data, data])
45
    return recursive_d3_data(
46
        current=current + 1,
47
        max_iters=max_iters,
48
        data=data)
49
50
51
def dates_list(max_dates=10):
52
    """Generate a timeseries dates list."""
53
    now = dt.now()
54
    return [str(now + td(days=i * 10))[0:10] for i in range(max_dates)]
55
56
57
def rr_list(max_range=10):
58
    """Generate a list of random integers."""
59
    return [rr(0, 100) for i in range(max_range)]
60
61
62
@cross_origin()
63
@app.route('/combination')
64
def combination():
65
    """Fake endpoint."""
66
    data = {
67
        'columns': [
68
            ['data1', 30, 20, 50, 40, 60, 50],
69
            ['data2', 200, 130, 90, 240, 130, 220],
70
            ['data3', 300, 200, 160, 400, 250, 250],
71
            ['data4', 200, 130, 90, 240, 130, 220],
72
            ['data5', 130, 120, 150, 140, 160, 150],
73
            ['data6', 90, 70, 20, 50, 60, 120],
74
        ],
75
        'type': 'bar',
76
        'types': {
77
            'data3': 'spline',
78
            'data4': 'line',
79
            'data6': 'area',
80
        },
81
        'groups': [
82
            ['data1', 'data2'],
83
        ]
84
    }
85
    return json.dumps(dict(data=data))
86
87
88
@cross_origin()
89
@app.route('/stacked-bar')
90
def stackedbar():
91
    """Fake endpoint."""
92
    return json.dumps({
93
        'data': {
94
            'columns': [
95
                ['data1', -30, 200, 200, 400, -150, 250],
96
                ['data2', 130, 100, -100, 200, -150, 50],
97
                ['data3', -230, 200, 200, -300, 250, 250]
98
            ],
99
            'type': 'bar',
100
            'groups': [
101
                ['data1', 'data2']
102
            ]
103
        },
104
        'grid': {
105
            'y': {
106
                'lines': [{'value': 0}]
107
            }
108
        }
109
    })
110
111
112
@cross_origin()
113
@app.route('/plotly')
114
def plotly():
115
    """Fake endpoint."""
116
    chart_type = request.args.get('chart', 'line')
117
    filename = '{}/examples/plotly/{}.json'.format(cwd, chart_type)
118
    with open(filename, 'r') as chartjson:
119
        return chartjson.read()
120
    return json.dumps({})
121
122
123
@cross_origin
124
@app.route('/plotly-dynamic')
125
def plotly_dynamic():
126
    """Fake endpoint."""
127
    filename = '{}/examples/plotly/bar_line_dynamic.json'.format(cwd)
128
    with open(filename, 'r') as chartjson:
129
        return chartjson.read()
130
    return json.dumps({})
131
132
133
@cross_origin()
134
@app.route('/timeline')
135
def timeline():
136
    """Fake endpoint."""
137
    with open('{}/examples/timeline3.json'.format(cwd), 'r') as timelinejson:
138
        return timelinejson.read()
139
    return json.dumps({})
140
141
142
@app.route('/dtable', methods=['GET'])
143
def dtable():
144
    """Fake endpoint."""
145
    if 'stress' in request.args:
146
        return json.dumps([
147
            dict(
148
                foo=rr(1, 1000),
149
                bar=rr(1, 1000),
150
                baz=rr(1, 1000),
151
                quux=rr(1, 1000)) for _ in range(STRESS_MAX_POINTS)
152
        ])
153
    fname = 'dtable-override' if 'override' in request.args else 'dtable'
154
    with open('{}/examples/{}.json'.format(os.getcwd(), fname), 'r') as djson:
155
        return djson.read()
156
    return json.dumps({})
157
158
159
@cross_origin()
160
@app.route('/timeseries')
161
def timeseries():
162
    """Fake endpoint."""
163
    return json.dumps({
164
        "dates": dates_list(),
165
        "line1": rr_list(max_range=10),
166
        "line2": rr_list(max_range=10),
167
        "line3": rr_list(max_range=10),
168
    })
169
170
171
@cross_origin()
172
@app.route('/custom')
173
def custompage():
174
    """Fake endpoint."""
175
    kwargs = dict(number=rr(1, 1000))
176
    return render_template('examples/custom.html', **kwargs)
177
178
179
@cross_origin()
180
@app.route('/gauge')
181
def gauge():
182
    """Fake endpoint."""
183
    return json.dumps({'data': rr(1, 100)})
184
185
186
@cross_origin()
187
@app.route('/area-custom')
188
def area_custom():
189
    """Fake endpoint."""
190
    return json.dumps({
191
        "data": {
192
            "columns": [
193
                ["data1", 300, 350, 300, 0, 0, 0],
194
                ["data2", 130, 100, 140, 200, 150, 50]
195
            ],
196
            "types": {
197
                "data1": "area",
198
                "data2": "area-spline"
199
            }
200
        }
201
    })
202
203
204
@cross_origin()
205
@app.route('/scatter')
206
def scatter():
207
    """Fake endpoint."""
208
    if 'override' in request.args:
209
        with open('{}/examples/overrides.json'.format(cwd), 'r') as jsonfile:
210
            return jsonfile.read()
211
    return json.dumps({
212
        "bar1": [1, 2, 30, 12, 100],
213
        "bar2": rr_list(max_range=40),
214
        "bar3": rr_list(max_range=40),
215
        "bar4": [-10, 1, 5, 4, 10, 20],
216
    })
217
218
219
@cross_origin()
220
@app.route('/pie')
221
def pie():
222
    """Fake endpoint."""
223
    letters = list('abcde')
224
    if 'stress' in request.args:
225
        letters = range(STRESS_MAX_POINTS)
226
    return json.dumps({'data {}'.format(name): rr(1, 100) for name in letters})
227
228
229
@cross_origin()
230
@app.route('/custom-inputs')
231
def custom_inputs():
232
    """Fake endpoint."""
233
    _range = int(request.args.get('range', 5))
234
    entries = int(request.args.get('entries', 3))
235
    return json.dumps({
236
        i: rr_list(max_range=_range) for i in range(entries)
237
    })
238
239
240
@cross_origin()
241
@app.route('/bar')
242
def barchart():
243
    """Fake endpoint."""
244
    if 'stress' in request.args:
245
        return json.dumps({
246
            'bar-{}'.format(k): rr_list(max_range=STRESS_MAX_POINTS)
247
            for k in range(STRESS_MAX_POINTS)
248
        })
249
    return json.dumps({
250
        "bar1": [1, 2, 30, 12, 100],
251
        "bar2": rr_list(max_range=5),
252
        "bar3": rr_list(max_range=5),
253
    })
254
255
256
@cross_origin()
257
@app.route('/line')
258
def linechart():
259
    """Fake endpoint."""
260
    if 'stress' in request.args:
261
        return json.dumps({
262
            'bar-{}'.format(k): rr_list(max_range=STRESS_MAX_POINTS)
263
            for k in range(STRESS_MAX_POINTS)
264
        })
265
    return json.dumps({
266
        "line1": [1, 4, 3, 10, 12, 14, 18, 10],
267
        "line2": [1, 2, 10, 20, 30, 6, 10, 12, 18, 2],
268
        "line3": rr_list(),
269
    })
270
271
272
@cross_origin()
273
@app.route('/singlenum')
274
def singlenum():
275
    """Fake endpoint."""
276
    _min, _max = 10, 10000
277
    if 'sales' in request.args:
278
        val = locale.currency(float(rr(_min, _max)), grouping=True)
279
    else:
280
        val = rr(_min, _max)
281
    if 'negative' in request.args:
282
        val = '-{}'.format(val)
283
    return json.dumps(val)
284
285
286
@cross_origin()
287
@app.route('/deadend')
288
def test_die():
289
    """Fake endpoint that ends in a random 50x error."""
290
    # Simulate slow connection
291
    time.sleep(random())
292
    abort(choice([500, 501, 502, 503, 504]))
293
294
295
@cross_origin()
296
@app.route('/venn')
297
def test_venn():
298
    """Fake endpoint."""
299
    data = [
300
        {'sets': ['A'], 'size': rr(10, 100)},
301
        {'sets': ['B'], 'size': rr(10, 100)},
302
        {'sets': ['C'], 'size': rr(10, 100)},
303
        {'sets': ['A', 'B'], 'size': rr(10, 100)},
304
        {'sets': ['A', 'B', 'C'], 'size': rr(10, 100)},
305
    ]
306
    return json.dumps(data)
307
308
309
@cross_origin()
310
@app.route('/sparklines', methods=['GET'])
311
def sparklines():
312
    """Fake endpoint."""
313
    if any([
314
        'pie' in request.args,
315
        'discrete' in request.args,
316
    ]):
317
        return json.dumps([rr(1, 100) for _ in range(10)])
318
    return json.dumps([[i, rr(i, 100)] for i in range(10)])
319
320
321
@cross_origin()
322
@app.route('/circlepack', methods=['GET'])
323
def circlepack():
324
    """Fake endpoint."""
325
    if 'stress' in request.args:
326
        # Build a very large dataset
327
        return json.dumps(recursive_d3_data())
328
    with open('{}/examples/flare.json'.format(cwd), 'r') as djson:
329
        return djson.read()
330
    return json.dumps({})
331
332
333
@cross_origin()
334
@app.route('/treemap', methods=['GET'])
335
def treemap():
336
    """Fake endpoint."""
337
    if 'stress' in request.args:
338
        # Build a very large dataset
339
        return json.dumps(recursive_d3_data())
340
    with open('{}/examples/flare.json'.format(cwd), 'r') as djson:
341
        return djson.read()
342
    return json.dumps({})
343
344
345
@cross_origin()
346
@app.route('/map', methods=['GET'])
347
def datamap():
348
    """Fake endpoint."""
349
    return render_template('examples/map.html')
350
351
352
@cross_origin()
353
@app.route('/dendrogram', methods=['GET'])
354
def dendro():
355
    """Fake endpoint."""
356
    if 'stress' in request.args:
357
        # Build a very large dataset
358
        return json.dumps(recursive_d3_data())
359
    filename = 'flare-simple' if 'simple' in request.args else 'flare'
360
    with open('{}/examples/{}.json'.format(cwd, filename), 'r') as djson:
361
        return djson.read()
362
    return json.dumps({})
363
364
365
@cross_origin()
366
@app.route('/voronoi', methods=['GET'])
367
def voronoi():
368
    """Fake endpoint."""
369
    w, h = request.args.get('width', 800), request.args.get('height', 800)
370
    max_points = int(request.args.get('points', 100))
371
    if 'stress' in request.args:
372
        max_points = 500
373
    return json.dumps([[rr(1, h), rr(1, w)] for _ in range(max_points)])
374
375
376
if __name__ == '__main__':
377
    app.run(debug=True, port=5004)
378