-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.py
More file actions
95 lines (76 loc) · 2.6 KB
/
Copy pathparser.py
File metadata and controls
95 lines (76 loc) · 2.6 KB
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
94
95
"""
parser.py — Parse call log CSV files and Telnyx CDR API responses.
"""
import csv
from datetime import datetime
REQUIRED_FIELDS = {"timestamp", "phone_number", "status"}
def parse_csv(filepath: str) -> list[dict]:
"""
Parse a call log CSV file into a list of call record dicts.
Args:
filepath: Path to the CSV file
Returns:
list of call record dicts
"""
records = []
with open(filepath, newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
fields = set(reader.fieldnames or [])
missing = REQUIRED_FIELDS - fields
if missing:
raise ValueError(f"CSV is missing required columns: {missing}")
for row in reader:
record = dict(row)
# Normalize timestamp
try:
record["timestamp"] = datetime.fromisoformat(record["timestamp"])
except (ValueError, KeyError):
record["timestamp"] = None
# Normalize duration to seconds
if "duration" in record:
record["duration_seconds"] = _parse_duration(record["duration"])
records.append(record)
return records
def parse_telnyx_cdr(api_response: list[dict]) -> list[dict]:
"""
Parse a list of Telnyx CDR API records into a normalized format.
Args:
api_response: List of CDR record dicts from the Telnyx API
Returns:
list of normalized call record dicts
"""
records = []
for item in api_response:
record = {
"timestamp": _parse_iso(item.get("start_time")),
"phone_number": item.get("to", ""),
"from_number": item.get("from", ""),
"status": item.get("status", "unknown"),
"duration_seconds": item.get("duration_secs", 0),
"call_id": item.get("call_leg_id", ""),
"direction": item.get("direction", "outbound"),
}
records.append(record)
return records
def _parse_duration(value: str) -> int:
"""Convert a duration string like '2m 14s' or '134' to integer seconds."""
if not value:
return 0
value = str(value).strip()
if value.isdigit():
return int(value)
total = 0
if "m" in value:
parts = value.split("m")
total += int(parts[0].strip()) * 60
value = parts[1]
if "s" in value:
total += int(value.replace("s", "").strip())
return total
def _parse_iso(value: str) -> datetime | None:
if not value:
return None
try:
return datetime.fromisoformat(value.replace("Z", "+00:00"))
except ValueError:
return None