Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1import json 

2from datasette.utils import ( 

3 value_as_boolean, 

4 remove_infinites, 

5 CustomJSONEncoder, 

6 path_from_row_pks, 

7) 

8 

9 

10def convert_specific_columns_to_json(rows, columns, json_cols): 

11 json_cols = set(json_cols) 

12 if not json_cols.intersection(columns): 

13 return rows 

14 new_rows = [] 

15 for row in rows: 

16 new_row = [] 

17 for value, column in zip(row, columns): 

18 if column in json_cols: 

19 try: 

20 value = json.loads(value) 

21 except (TypeError, ValueError) as e: 

22 print(e) 

23 pass 

24 new_row.append(value) 

25 new_rows.append(new_row) 

26 return new_rows 

27 

28 

29def json_renderer(args, data, view_name): 

30 """ Render a response as JSON """ 

31 status_code = 200 

32 # Handle the _json= parameter which may modify data["rows"] 

33 json_cols = [] 

34 if "_json" in args: 

35 json_cols = args.getlist("_json") 

36 if json_cols and "rows" in data and "columns" in data: 

37 data["rows"] = convert_specific_columns_to_json( 

38 data["rows"], data["columns"], json_cols 

39 ) 

40 

41 # unless _json_infinity=1 requested, replace infinity with None 

42 if "rows" in data and not value_as_boolean(args.get("_json_infinity", "0")): 

43 data["rows"] = [remove_infinites(row) for row in data["rows"]] 

44 

45 # Deal with the _shape option 

46 shape = args.get("_shape", "arrays") 

47 if shape == "arrayfirst": 

48 data = [row[0] for row in data["rows"]] 

49 elif shape in ("objects", "object", "array"): 

50 columns = data.get("columns") 

51 rows = data.get("rows") 

52 if rows and columns: 

53 data["rows"] = [dict(zip(columns, row)) for row in rows] 

54 if shape == "object": 

55 error = None 

56 if "primary_keys" not in data: 

57 error = "_shape=object is only available on tables" 

58 else: 

59 pks = data["primary_keys"] 

60 if not pks: 

61 error = ( 

62 "_shape=object not available for tables with no primary keys" 

63 ) 

64 else: 

65 object_rows = {} 

66 for row in data["rows"]: 

67 pk_string = path_from_row_pks(row, pks, not pks) 

68 object_rows[pk_string] = row 

69 data = object_rows 

70 if error: 

71 data = {"ok": False, "error": error} 

72 elif shape == "array": 

73 data = data["rows"] 

74 elif shape == "arrays": 

75 pass 

76 else: 

77 status_code = 400 

78 data = { 

79 "ok": False, 

80 "error": "Invalid _shape: {}".format(shape), 

81 "status": 400, 

82 "title": None, 

83 } 

84 # Handle _nl option for _shape=array 

85 nl = args.get("_nl", "") 

86 if nl and shape == "array": 

87 body = "\n".join(json.dumps(item) for item in data) 

88 content_type = "text/plain" 

89 else: 

90 body = json.dumps(data, cls=CustomJSONEncoder) 

91 content_type = "application/json; charset=utf-8" 

92 return {"body": body, "status_code": status_code, "content_type": content_type}