Coverage for polar/kit/csv.py: 28%
40 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 17:15 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 17:15 +0000
1import collections 1a
2import csv 1a
3from collections.abc import Iterable 1a
4from typing import TYPE_CHECKING, Any, BinaryIO 1a
6if TYPE_CHECKING: 6 ↛ 7line 6 didn't jump to line 7 because the condition on line 6 was never true1a
7 import _csv
9from .email import EmailNotValidError, validate_email 1a
12def get_iterable_from_binary_io(file: BinaryIO) -> Iterable[str]: 1a
13 for line in file:
14 yield line.decode("utf-8")
17def get_emails_from_csv(lines: Iterable[str]) -> set[str]: 1a
18 emails: set[str] = set()
20 reader = csv.DictReader(lines)
21 if reader.fieldnames is None:
22 return emails
24 try:
25 email_field = next(
26 field for field in reader.fieldnames if "email" in field.lower()
27 )
28 except StopIteration:
29 return emails
31 for row in reader:
32 email = row.get(email_field)
33 if email is not None:
34 try:
35 validate_email(email)
36 except EmailNotValidError:
37 continue
38 else:
39 emails.add(email)
41 return emails
44class IterableCSVWriter: 1a
45 """
46 Utility class wrapping the built-in csv.writer allowing
47 to generate CSV rows as strings.
49 It's useful to generate CSV with StreamingResponse, for example.
50 """
52 writer: "_csv._writer"
54 def __init__( 1a
55 self,
56 dialect: "_csv._DialectLike" = "excel",
57 *,
58 delimiter: str = ",",
59 quotechar: str | None = '"',
60 escapechar: str | None = None,
61 doublequote: bool = True,
62 skipinitialspace: bool = False,
63 lineterminator: str = "\r\n",
64 quoting: "_csv._QuotingType" = 0,
65 strict: bool = False,
66 ) -> None:
67 self._lines: collections.deque[str] = collections.deque()
68 self.writer = csv.writer(
69 self,
70 dialect=dialect,
71 delimiter=delimiter,
72 quotechar=quotechar,
73 escapechar=escapechar,
74 doublequote=doublequote,
75 skipinitialspace=skipinitialspace,
76 lineterminator=lineterminator,
77 quoting=quoting,
78 strict=strict,
79 )
81 def getrow(self, row: Iterable[Any]) -> str: 1a
82 self.writer.writerow(row)
83 return self.read()
85 def write(self, line: str) -> None: 1a
86 self._lines.append(line)
88 def read(self) -> str: 1a
89 return self._lines.popleft()