zip2info 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
zip2info/__init__.py ADDED
@@ -0,0 +1,95 @@
1
+ from dataclasses import dataclass
2
+ from typing import Optional
3
+
4
+ from zip2info._data import TIMEZONES, ZIP_INFO
5
+
6
+
7
+ @dataclass(frozen=True, slots=True)
8
+ class ZipInfo:
9
+ """Metadata for a US ZIP code."""
10
+
11
+ zipcode: int
12
+ timezone: str
13
+ latitude: float
14
+ longitude: float
15
+
16
+
17
+ def _normalize_zipcode(zipcode: str | int) -> Optional[int]:
18
+ try:
19
+ return int(zipcode)
20
+ except (ValueError, TypeError):
21
+ return None
22
+
23
+
24
+ def timezone(zipcode: str | int) -> Optional[str]:
25
+ """
26
+ Return the IANA timezone for a US ZIP code.
27
+
28
+ Args:
29
+ zipcode: ZIP code as a string or integer.
30
+
31
+ Returns:
32
+ Timezone string (for example, ``America/New_York``) or ``None``.
33
+ """
34
+ zip_int = _normalize_zipcode(zipcode)
35
+ if zip_int is None:
36
+ return None
37
+
38
+ record = ZIP_INFO.get(zip_int)
39
+ if record is None:
40
+ return None
41
+ tz_idx, _, _ = record
42
+ return TIMEZONES[tz_idx]
43
+
44
+
45
+ def coordinates(zipcode: str | int) -> Optional[tuple[float, float]]:
46
+ """
47
+ Return centroid latitude and longitude for a US ZIP code.
48
+
49
+ Coordinates come from the generated ZIP metadata dataset.
50
+
51
+ Args:
52
+ zipcode: ZIP code as a string or integer.
53
+
54
+ Returns:
55
+ ``(latitude, longitude)`` or ``None``.
56
+ """
57
+ zip_int = _normalize_zipcode(zipcode)
58
+ if zip_int is None:
59
+ return None
60
+
61
+ record = ZIP_INFO.get(zip_int)
62
+ if record is None:
63
+ return None
64
+ _, latitude, longitude = record
65
+ return latitude, longitude
66
+
67
+
68
+ def info(zipcode: str | int) -> Optional[ZipInfo]:
69
+ """
70
+ Return timezone and coordinate metadata for a US ZIP code.
71
+
72
+ Args:
73
+ zipcode: ZIP code as a string or integer.
74
+
75
+ Returns:
76
+ ``ZipInfo`` when timezone data exists, otherwise ``None``.
77
+ """
78
+ zip_int = _normalize_zipcode(zipcode)
79
+ if zip_int is None:
80
+ return None
81
+
82
+ record = ZIP_INFO.get(zip_int)
83
+ if record is None:
84
+ return None
85
+
86
+ tz_idx, latitude, longitude = record
87
+ return ZipInfo(
88
+ zipcode=zip_int,
89
+ timezone=TIMEZONES[tz_idx],
90
+ latitude=latitude,
91
+ longitude=longitude,
92
+ )
93
+
94
+
95
+ __all__ = ["ZipInfo", "coordinates", "info", "timezone"]