python-benedict/benedict/serializers/csv.py

69 lines
2.0 KiB
Python
Raw Normal View History

import csv
from io import StringIO
from benedict.serializers.abstract import AbstractSerializer
from benedict.utils import type_util
class CSVSerializer(AbstractSerializer):
2022-02-13 10:56:44 +00:00
"""
This class describes a csv serializer.
"""
def __init__(self):
super().__init__(
extensions=[
"csv",
],
)
def decode(self, s, **kwargs):
# kwargs.setdefault('delimiter', ',')
2022-02-13 10:35:43 +00:00
if kwargs.pop("quote", False):
# TODO: add tests coverage
2022-02-13 10:35:43 +00:00
kwargs.setdefault("quoting", csv.QUOTE_ALL)
columns = kwargs.pop("columns", None)
columns_row = kwargs.pop("columns_row", True)
f = StringIO(s)
r = csv.reader(f, **kwargs)
ln = 0
data = []
for row in r:
if ln == 0 and columns_row:
if not columns:
columns = row
ln += 1
continue
d = dict(zip(columns, row))
data.append(d)
ln += 1
return data
def encode(self, d, **kwargs):
2022-03-24 12:26:18 +00:00
ls = d
# kwargs.setdefault('delimiter', ',')
2022-02-13 10:35:43 +00:00
if kwargs.pop("quote", False):
kwargs.setdefault("quoting", csv.QUOTE_ALL)
kwargs.setdefault("lineterminator", "\n")
columns = kwargs.pop("columns", None)
columns_row = kwargs.pop("columns_row", True)
2022-03-24 12:26:18 +00:00
if not columns and len(ls) and type_util.is_dict(ls[0]):
keys = [str(key) for key in ls[0].keys()]
columns = list(sorted(keys))
f = StringIO()
w = csv.writer(f, **kwargs)
if columns_row and columns:
w.writerow(columns)
2022-03-24 12:26:18 +00:00
for item in ls:
if type_util.is_dict(item):
2022-02-13 10:35:43 +00:00
row = [item.get(key, "") for key in columns]
elif type_util.is_collection(item):
# TODO: add tests coverage
row = item
else:
# TODO: add tests coverage
row = [item]
w.writerow(row)
data = f.getvalue()
return data