File: to_json.py

package info (click to toggle)
python-agate 1.9.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,996 kB
  • sloc: python: 8,512; makefile: 126
file content (93 lines) | stat: -rw-r--r-- 2,847 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import json
import os
from collections import OrderedDict


def to_json(self, path, key=None, newline=False, indent=None, **kwargs):
    """
    Write this table to a JSON file or file-like object.

    :code:`kwargs` will be passed through to the JSON encoder.

    :param path:
        File path or file-like object to write to.
    :param key:
        If specified, JSON will be output as an hash instead of a list. May
        be either the name of a column from the this table containing
        unique values or a :class:`function` that takes a row and returns
        a unique value.
    :param newline:
        If `True`, output will be in the form of "newline-delimited JSON".
    :param indent:
        If specified, the number of spaces to indent the JSON for
        formatting.
    """
    if key is not None and newline:
        raise ValueError('key and newline may not be specified together.')

    if newline and indent is not None:
        raise ValueError('newline and indent may not be specified together.')

    key_is_row_function = hasattr(key, '__call__')

    json_kwargs = {
        'ensure_ascii': False,
        'indent': indent
    }

    # Pass remaining kwargs through to JSON encoder
    json_kwargs.update(kwargs)

    json_funcs = [c.jsonify for c in self._column_types]

    close = True
    f = None

    try:
        if hasattr(path, 'write'):
            f = path
            close = False
        else:
            if os.path.dirname(path) and not os.path.exists(os.path.dirname(path)):
                os.makedirs(os.path.dirname(path))
            f = open(path, 'w')

        def dump_json(data):
            json.dump(data, f, **json_kwargs)

            if newline:
                f.write('\n')

        # Keyed
        if key is not None:
            output = OrderedDict()

            for row in self._rows:
                if key_is_row_function:
                    k = key(row)
                else:
                    k = str(row[key])

                if k in output:
                    raise ValueError('Value %s is not unique in the key column.' % str(k))

                values = tuple(json_funcs[i](d) for i, d in enumerate(row))
                output[k] = OrderedDict(zip(row.keys(), values))
            dump_json(output)
        # Newline-delimited
        elif newline:
            for row in self._rows:
                values = tuple(json_funcs[i](d) for i, d in enumerate(row))
                dump_json(OrderedDict(zip(row.keys(), values)))
        # Normal
        else:
            output = []

            for row in self._rows:
                values = tuple(json_funcs[i](d) for i, d in enumerate(row))
                output.append(OrderedDict(zip(row.keys(), values)))

            dump_json(output)
    finally:
        if close and f is not None:
            f.close()