mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
parent
b46e370ee6
commit
f643f7aee1
2 changed files with 46 additions and 2 deletions
29
app.py
29
app.py
|
|
@ -8,6 +8,7 @@ from pathlib import Path
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import json
|
import json
|
||||||
|
import base64
|
||||||
import hashlib
|
import hashlib
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
@ -99,8 +100,15 @@ class BaseView(HTTPMethodView):
|
||||||
'error': str(e),
|
'error': str(e),
|
||||||
}
|
}
|
||||||
if as_json:
|
if as_json:
|
||||||
r = response.json(data)
|
r = response.HTTPResponse(
|
||||||
r.headers['Access-Control-Allow-Origin'] = '*'
|
json.dumps(
|
||||||
|
data, cls=CustomJSONEncoder
|
||||||
|
),
|
||||||
|
content_type='application/json',
|
||||||
|
headers={
|
||||||
|
'Access-Control-Allow-Origin': '*'
|
||||||
|
}
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
context = {**data, **dict(
|
context = {**data, **dict(
|
||||||
extra_template_data()
|
extra_template_data()
|
||||||
|
|
@ -159,6 +167,7 @@ class TableView(BaseView):
|
||||||
rows = conn.execute('select * from {} limit 20'.format(table))
|
rows = conn.execute('select * from {} limit 20'.format(table))
|
||||||
columns = [r[0] for r in rows.description]
|
columns = [r[0] for r in rows.description]
|
||||||
pks = pks_for_table(conn, table)
|
pks = pks_for_table(conn, table)
|
||||||
|
rows = list(rows)
|
||||||
return {
|
return {
|
||||||
'database': name,
|
'database': name,
|
||||||
'table': table,
|
'table': table,
|
||||||
|
|
@ -266,6 +275,22 @@ def path_from_row_pks(row, pks):
|
||||||
return ','.join(bits)
|
return ','.join(bits)
|
||||||
|
|
||||||
|
|
||||||
|
class CustomJSONEncoder(json.JSONEncoder):
|
||||||
|
def default(self, obj):
|
||||||
|
if isinstance(obj, sqlite3.Row):
|
||||||
|
return dict(obj)
|
||||||
|
if isinstance(obj, bytes):
|
||||||
|
# Does it encode to utf8?
|
||||||
|
try:
|
||||||
|
return obj.decode('utf8')
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
return {
|
||||||
|
'$base64': True,
|
||||||
|
'encoded': base64.b64encode(obj).decode('latin1'),
|
||||||
|
}
|
||||||
|
return json.JSONEncoder.default(self, obj)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if '--build' in sys.argv:
|
if '--build' in sys.argv:
|
||||||
ensure_build_metadata(True)
|
ensure_build_metadata(True)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import app
|
import app
|
||||||
import pytest
|
import pytest
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('path,expected', [
|
@pytest.mark.parametrize('path,expected', [
|
||||||
|
|
@ -45,3 +46,21 @@ def test_pks_for_table(sql, table, expected_keys):
|
||||||
def test_path_from_row_pks(row, pks, expected_path):
|
def test_path_from_row_pks(row, pks, expected_path):
|
||||||
actual_path = app.path_from_row_pks(row, pks)
|
actual_path = app.path_from_row_pks(row, pks)
|
||||||
assert expected_path == actual_path
|
assert expected_path == actual_path
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('obj,expected', [
|
||||||
|
({
|
||||||
|
'Description': 'Soft drinks',
|
||||||
|
'Picture': b"\x15\x1c\x02\xc7\xad\x05\xfe",
|
||||||
|
'CategoryID': 1,
|
||||||
|
}, """
|
||||||
|
{"CategoryID": 1, "Description": "Soft drinks", "Picture": {"$base64": true, "encoded": "FRwCx60F/g=="}}
|
||||||
|
""".strip()),
|
||||||
|
])
|
||||||
|
def test_custom_json_encoder(obj, expected):
|
||||||
|
actual = json.dumps(
|
||||||
|
obj,
|
||||||
|
cls=app.CustomJSONEncoder,
|
||||||
|
sort_keys=True
|
||||||
|
)
|
||||||
|
assert expected == actual
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue