Skip to content

Commit 65ecd41

Browse files
committed
Limit response size in simple query db
1 parent 6e22d69 commit 65ecd41

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

budgetkey_api/modules/simpledb.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import json
99
from hashlib import md5
1010

11-
from flask import Blueprint, abort, current_app, request
11+
from flask import Blueprint, abort, current_app, request, Response
1212
from flask_jsonpify import jsonpify
1313

1414
from sqlalchemy import create_engine, text
@@ -148,6 +148,8 @@ def fetch_table(self, table):
148148

149149
class SimpleDBBlueprint(Blueprint):
150150

151+
MAX_PAYLOAD_SIZE = 250 * 1024 # 250 KB
152+
151153
def __init__(self, connection_string, search_blueprint, db_blueprint):
152154
super().__init__('simpledb', 'simpledb')
153155
self.tables = TableHolder(connection_string)
@@ -194,6 +196,30 @@ def get_table(self, table):
194196
def get_tables(self):
195197
return jsonpify(self.tables.TABLES)
196198

199+
def trim_json(self, data, max_size):
200+
ret = dict(
201+
download_url=data.get('download_url'),
202+
warnings=data.get('warnings'),
203+
num_rows=0,
204+
total_rows=data.get('total', 0),
205+
rows=[]
206+
)
207+
rows = data.get('rows', [])
208+
ret_json = json.dumps(ret, ensure_ascii=False)
209+
current_len = len(ret_json)
210+
trimmed_rows = []
211+
for row in rows:
212+
row_json = json.dumps(row, ensure_ascii=False)
213+
current_len += len(row_json) + 1
214+
if current_len > max_size:
215+
break
216+
else:
217+
trimmed_rows.append(row)
218+
ret['num_rows'] = len(trimmed_rows)
219+
ret['rows'] = trimmed_rows
220+
ret_json = json.dumps(ret, ensure_ascii=False)
221+
return ret_json
222+
197223
def query_table(self, table):
198224
ret = self.tables.get_info(table)
199225
if ret is None:
@@ -210,7 +236,8 @@ def query_table(self, table):
210236
warnings = check_for_common_errors(table, sql)
211237
if warnings:
212238
ret['warnings'] = warnings
213-
return jsonpify(ret)
239+
ret = self.trim_json(ret, self.MAX_PAYLOAD_SIZE)
240+
return Response(ret, mimetype='application/json')
214241

215242
def simple_search(self, table):
216243
params = self.tables.get_search_params(table)

0 commit comments

Comments
 (0)