Completed
Push — master ( 9ed7d2...2193e1 )
by Chris
01:25
created

recursive_d3_data()   A

Complexity

Conditions 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
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('/bar')
231
def barchart():
232
    """Fake endpoint."""
233
    if 'stress' in request.args:
234
        return json.dumps({
235
            'bar-{}'.format(k): rr_list(max_range=STRESS_MAX_POINTS)
236
            for k in range(STRESS_MAX_POINTS)
237
        })
238
    return json.dumps({
239
        "bar1": [1, 2, 30, 12, 100],
240
        "bar2": rr_list(max_range=5),
241
        "bar3": rr_list(max_range=5),
242
    })
243
244
245
@cross_origin()
246
@app.route('/line')
247
def linechart():
248
    """Fake endpoint."""
249
    if 'stress' in request.args:
250
        return json.dumps({
251
            'bar-{}'.format(k): rr_list(max_range=STRESS_MAX_POINTS)
252
            for k in range(STRESS_MAX_POINTS)
253
        })
254
    return json.dumps({
255
        "line1": [1, 4, 3, 10, 12, 14, 18, 10],
256
        "line2": [1, 2, 10, 20, 30, 6, 10, 12, 18, 2],
257
        "line3": rr_list(),
258
    })
259
260
261
@cross_origin()
262
@app.route('/singlenum')
263
def singlenum():
264
    """Fake endpoint."""
265
    _min, _max = 10, 10000
266
    if 'sales' in request.args:
267
        val = locale.currency(float(rr(_min, _max)), grouping=True)
268
    else:
269
        val = rr(_min, _max)
270
    if 'negative' in request.args:
271
        val = '-{}'.format(val)
272
    return json.dumps(val)
273
274
275
@cross_origin()
276
@app.route('/deadend')
277
def test_die():
278
    """Fake endpoint that ends in a random 50x error."""
279
    # Simulate slow connection
280
    time.sleep(random())
281
    abort(choice([500, 501, 502, 503, 504]))
282
283
284
@cross_origin()
285
@app.route('/venn')
286
def test_venn():
287
    """Fake endpoint."""
288
    data = [
289
        {'sets': ['A'], 'size': rr(10, 100)},
290
        {'sets': ['B'], 'size': rr(10, 100)},
291
        {'sets': ['C'], 'size': rr(10, 100)},
292
        {'sets': ['A', 'B'], 'size': rr(10, 100)},
293
        {'sets': ['A', 'B', 'C'], 'size': rr(10, 100)},
294
    ]
295
    return json.dumps(data)
296
297
298
@cross_origin()
299
@app.route('/sparklines', methods=['GET'])
300
def sparklines():
301
    """Fake endpoint."""
302
    if any([
303
        'pie' in request.args,
304
        'discrete' in request.args,
305
    ]):
306
        return json.dumps([rr(1, 100) for _ in range(10)])
307
    return json.dumps([[i, rr(i, 100)] for i in range(10)])
308
309
310
@cross_origin()
311
@app.route('/circlepack', methods=['GET'])
312
def circlepack():
313
    """Fake endpoint."""
314
    if 'stress' in request.args:
315
        # Build a very large dataset
316
        return json.dumps(recursive_d3_data())
317
    with open('{}/examples/flare.json'.format(cwd), 'r') as djson:
318
        return djson.read()
319
    return json.dumps({})
320
321
322
@cross_origin()
323
@app.route('/treemap', methods=['GET'])
324
def treemap():
325
    """Fake endpoint."""
326
    if 'stress' in request.args:
327
        # Build a very large dataset
328
        return json.dumps(recursive_d3_data())
329
    with open('{}/examples/flare.json'.format(cwd), 'r') as djson:
330
        return djson.read()
331
    return json.dumps({})
332
333
334
@cross_origin()
335
@app.route('/map', methods=['GET'])
336
def datamap():
337
    """Fake endpoint."""
338
    return render_template('examples/map.html')
339
340
341
@cross_origin()
342
@app.route('/dendrogram', methods=['GET'])
343
def dendro():
344
    """Fake endpoint."""
345
    if 'stress' in request.args:
346
        # Build a very large dataset
347
        return json.dumps(recursive_d3_data())
348
    filename = 'flare-simple' if 'simple' in request.args else 'flare'
349
    with open('{}/examples/{}.json'.format(cwd, filename), 'r') as djson:
350
        return djson.read()
351
    return json.dumps({})
352
353
354
@cross_origin()
355
@app.route('/voronoi', methods=['GET'])
356
def voronoi():
357
    """Fake endpoint."""
358
    w, h = request.args.get('width', 800), request.args.get('height', 800)
359
    max_points = int(request.args.get('points', 100))
360
    if 'stress' in request.args:
361
        max_points = 500
362
    return json.dumps([[rr(1, h), rr(1, w)] for _ in range(max_points)])
363
364
365
if __name__ == '__main__':
366
    app.run(debug=True, port=5004)
367