Passed
Pull Request — master (#40)
by
unknown
01:20
created

benedict.dicts.io.io_dict.IODict.to_csv()   A

Complexity

Conditions 1

Size

Total Lines 11
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 11
rs 10
c 0
b 0
f 0
cc 1
nop 5
1
# -*- coding: utf-8 -*-
2
3
from benedict.dicts.base import BaseDict
4
from benedict.dicts.io import io_util
5
from benedict.utils import type_util
6
7
8
class IODict(BaseDict):
9
10
    def __init__(self, *args, **kwargs):
11
        """
12
        Constructs a new instance.
13
        """
14
        # if first argument is data-string, url or filepath try to decode it.
15
        # use 'format' kwarg to specify the decoder to use, default 'json'.
16
        if len(args) == 1 and type_util.is_string(args[0]):
17
            d = IODict._decode_init(args[0], **kwargs)
18
            super(IODict, self).__init__(d)
19
            return
20
        super(IODict, self).__init__(*args, **kwargs)
21
22
    @staticmethod
23
    def _decode_init(s, **kwargs):
24
        autodetected_format = io_util.autodetect_format(s)
25
        default_format = autodetected_format or 'json'
26
        format = kwargs.pop('format', default_format).lower()
27
        if format in ['b64', 'base64']:
28
            kwargs.setdefault('subformat', 'json')
29
        # decode data-string and initialize with dict data.
30
        return IODict._decode(s, format, **kwargs)
31
32
    @staticmethod
33
    def _decode(s, format, **kwargs):
34
        try:
35
            content = io_util.read_content(s)
36
            # decode content using the given format
37
            data = io_util.decode(content, format, **kwargs)
38
            if type_util.is_dict(data):
39
                return data
40
            elif type_util.is_list(data):
41
                # force list to dict
42
                return {
43
                    'values': data
44
                }
45
            else:
46
                raise ValueError(
47
                        'Invalid data type: {}, expected dict or list.'.format(
48
                                type(data)))
49
        except Exception as e:
50
            raise ValueError(
51
                    'Invalid data or url or filepath argument: {}\n{}'.format(
52
                            s, e))
53
54
    @staticmethod
55
    def _encode(d, format, **kwargs):
56
        filepath = kwargs.pop('filepath', None)
57
        s = io_util.encode(d, format, **kwargs)
58
        if filepath:
59
            io_util.write_file(filepath, s)
60
        return s
61
62
    @classmethod
63
    def from_base64(cls, s, subformat='json', encoding='utf-8', **kwargs):
64
        """
65
        Load and decode Base64 data from url, filepath or data-string.
66
        Data is decoded according to subformat and encoding.
67
        Decoder specific options can be passed using kwargs.
68
        Return a new dict instance. A ValueError is raised in case of failure.
69
        """
70
        kwargs['subformat'] = subformat
71
        kwargs['encoding'] = encoding
72
        return cls(s, format='base64', **kwargs)
73
74
    @classmethod
75
    def from_csv(cls, s, columns=None, columns_row=True, **kwargs):
76
        """
77
        Load and decode CSV data from url, filepath or data-string.
78
        Decoder specific options can be passed using kwargs:
79
        https://docs.python.org/3/library/csv.html
80
        Return a new dict instance. A ValueError is raised in case of failure.
81
        """
82
        kwargs['columns'] = columns
83
        kwargs['columns_row'] = columns_row
84
        return cls(s, format='csv', **kwargs)
85
86
    @classmethod
87
    def from_json(cls, s, **kwargs):
88
        """
89
        Load and decode JSON data from url, filepath or data-string.
90
        Decoder specific options can be passed using kwargs:
91
        https://docs.python.org/3/library/json.html
92
        Return a new dict instance. A ValueError is raised in case of failure.
93
        """
94
        return cls(s, format='json', **kwargs)
95
96
    @classmethod
97
    def from_pickle(cls, s, **kwargs):
98
        """
99
        Load and decode a pickle encoded in Base64 format data from url, filepath or data-string.
100
        Decoder specific options can be passed using kwargs:
101
        https://docs.python.org/3/library/pickle.html
102
        Return a new dict instance. A ValueError is raised in case of failure.
103
        """
104
        return cls(s, format='pickle', **kwargs)
105
106
    @classmethod
107
    def from_plist(cls, s, **kwargs):
108
        """
109
        Load and decode p-list data from url, filepath or data-string.
110
        Decoder specific options can be passed using kwargs:
111
        https://docs.python.org/3/library/plistlib.html
112
        Return a new dict instance. A ValueError is raised in case of failure.
113
        """
114
        return cls(s, format='plist', **kwargs)
115
116
    @classmethod
117
    def from_query_string(cls, s, **kwargs):
118
        """
119
        Load and decode query-string from url, filepath or data-string.
120
        Return a new dict instance. A ValueError is raised in case of failure.
121
        """
122
        return cls(s, format='query_string', **kwargs)
123
124
    @classmethod
125
    def from_toml(cls, s, **kwargs):
126
        """
127
        Load and decode TOML data from url, filepath or data-string.
128
        Decoder specific options can be passed using kwargs:
129
        https://pypi.org/project/toml/
130
        Return a new dict instance. A ValueError is raised in case of failure.
131
        """
132
        return cls(s, format='toml', **kwargs)
133
134
    @classmethod
135
    def from_xml(cls, s, **kwargs):
136
        """
137
        Load and decode XML data from url, filepath or data-string.
138
        Decoder specific options can be passed using kwargs:
139
        https://github.com/martinblech/xmltodict
140
        Return a new dict instance. A ValueError is raised in case of failure.
141
        """
142
        return cls(s, format='xml', **kwargs)
143
144
    @classmethod
145
    def from_yaml(cls, s, **kwargs):
146
        """
147
        Load and decode YAML data from url, filepath or data-string.
148
        Decoder specific options can be passed using kwargs:
149
        https://pyyaml.org/wiki/PyYAMLDocumentation
150
        Return a new dict instance. A ValueError is raised in case of failure.
151
        """
152
        return cls(s, format='yaml', **kwargs)
153
154
    def to_base64(self, subformat='json', encoding='utf-8', **kwargs):
155
        """
156
        Encode the current dict instance in Base64 format
157
        using the given subformat and encoding.
158
        Encoder specific options can be passed using kwargs.
159
        Return the encoded string and optionally save it at 'filepath'.
160
        A ValueError is raised in case of failure.
161
        """
162
        kwargs['subformat'] = subformat
163
        kwargs['encoding'] = encoding
164
        return self._encode(self, 'base64', **kwargs)
165
166
    def to_csv(self, key='values', columns=None, columns_row=True, **kwargs):
167
        """
168
        Encode the current dict instance in CSV format.
169
        Encoder specific options can be passed using kwargs:
170
        https://docs.python.org/3/library/csv.html
171
        Return the encoded string and optionally save it at 'filepath'.
172
        A ValueError is raised in case of failure.
173
        """
174
        kwargs['columns'] = columns
175
        kwargs['columns_row'] = columns_row
176
        return self._encode(self[key], 'csv', **kwargs)
177
178
    def to_json(self, **kwargs):
179
        """
180
        Encode the current dict instance in JSON format.
181
        Encoder specific options can be passed using kwargs:
182
        https://docs.python.org/3/library/json.html
183
        Return the encoded string and optionally save it at 'filepath'.
184
        A ValueError is raised in case of failure.
185
        """
186
        return self._encode(self, 'json', **kwargs)
187
188
    def to_ini(self, **kwargs):
189
        """
190
        Encode the current dict instance in JSON format.
191
        Encoder specific options can be passed using kwargs:
192
        https://docs.python.org/3/library/json.html
193
        Return the encoded string and optionally save it at 'filepath'.
194
        A ValueError is raised in case of failure.
195
        """
196
        return self._encode(self, 'ini', **kwargs)
197
198
    def to_pickle(self, **kwargs):
199
        """
200
        Encode the current dict instance as pickle (encoded in Base64).
201
        The pickle protocol used by default is 2.
202
        Encoder specific options can be passed using kwargs:
203
        https://docs.python.org/3/library/pickle.html
204
        Return the encoded string and optionally save it at 'filepath'.
205
        A ValueError is raised in case of failure.
206
        """
207
        return self._encode(self, 'pickle', **kwargs)
208
209
    def to_plist(self, **kwargs):
210
        """
211
        Encode the current dict instance as p-list.
212
        Encoder specific options can be passed using kwargs:
213
        https://docs.python.org/3/library/plistlib.html
214
        Return the encoded string and optionally save it at 'filepath'.
215
        A ValueError is raised in case of failure.
216
        """
217
        return self._encode(self, 'plist', **kwargs)
218
219
    def to_query_string(self, **kwargs):
220
        """
221
        Encode the current dict instance in query-string format.
222
        Return the encoded string and optionally save it at 'filepath'.
223
        A ValueError is raised in case of failure.
224
        """
225
        return self._encode(self, 'query_string', **kwargs)
226
227
    def to_toml(self, **kwargs):
228
        """
229
        Encode the current dict instance in TOML format.
230
        Encoder specific options can be passed using kwargs:
231
        https://pypi.org/project/toml/
232
        Return the encoded string and optionally save it at 'filepath'.
233
        A ValueError is raised in case of failure.
234
        """
235
        return self._encode(self, 'toml', **kwargs)
236
237
    def to_xml(self, **kwargs):
238
        """
239
        Encode the current dict instance in XML format.
240
        Encoder specific options can be passed using kwargs:
241
        https://github.com/martinblech/xmltodict
242
        Return the encoded string and optionally save it at 'filepath'.
243
        A ValueError is raised in case of failure.
244
        """
245
        return self._encode(self, 'xml', **kwargs)
246
247
    def to_yaml(self, **kwargs):
248
        """
249
        Encode the current dict instance in YAML format.
250
        Encoder specific options can be passed using kwargs:
251
        https://pyyaml.org/wiki/PyYAMLDocumentation
252
        Return the encoded string and optionally save it at 'filepath'.
253
        A ValueError is raised in case of failure.
254
        """
255
        return self._encode(self, 'yaml', **kwargs)
256