benedict.dicts.io.io_dict.IODict.to_base64()   A
last analyzed

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