|
3 | 3 | from io import StringIO |
4 | 4 | from json import loads |
5 | 5 | from xml.etree.ElementTree import Element, fromstring |
| 6 | +from urllib.parse import urlencode |
6 | 7 |
|
7 | 8 | import requests |
8 | 9 |
|
9 | | -from pyzipcodeapi.dataclass import Distance, Error, MultiDistance, Radius |
| 10 | +from pyzipcodeapi.dataclass import Distance, Error, MultiDistance, Radius, MultiRadius |
10 | 11 | from pyzipcodeapi.enums import FormatEnum, UnitEnum, CountryEnum |
11 | 12 | from pyzipcodeapi.options import OPTIONS |
12 | 13 |
|
@@ -111,10 +112,15 @@ def _api_call( |
111 | 112 | path: str, |
112 | 113 | data_class: type | None = None, |
113 | 114 | country: CountryEnum = CountryEnum.US, |
| 115 | + method: str = "GET", |
| 116 | + body: str | None = None, |
114 | 117 | ) -> DictReader | bytes | type | Element | Error: |
115 | 118 | base_url = f"rest/v2/CA" if country == CountryEnum.CA else f"rest" |
| 119 | + headers = {} |
| 120 | + if method != "GET": |
| 121 | + headers = {"Content-type": "application/x-www-form-urlencoded"} |
116 | 122 | self.con.request( |
117 | | - method="GET", url=f"/{base_url}/{self.api_key}/{option}.{f}/{path}" |
| 123 | + method, f"/{base_url}/{self.api_key}/{option}.{f}/{path}", body, headers |
118 | 124 | ) |
119 | 125 | response = self.con.getresponse() |
120 | 126 | success = response.status == 200 |
@@ -172,3 +178,25 @@ def radius( |
172 | 178 | if minimal: |
173 | 179 | path = f"{path}?minimal" |
174 | 180 | return self._api_call("radius", f, path, dc, country=country) |
| 181 | + |
| 182 | + def multi_radius( |
| 183 | + self, |
| 184 | + distance: int, |
| 185 | + zip_codes: list[str] | None = None, |
| 186 | + addresses: list[str] | None = None, |
| 187 | + units: UnitEnum = UnitEnum.KM, |
| 188 | + f: FormatEnum | None = FormatEnum.JSON, |
| 189 | + ) -> MultiRadius | DictReader | Element: |
| 190 | + """multi-radius.<format>/<distance>/<units>""" |
| 191 | + assert len(zip_codes) <= 100 |
| 192 | + if zip_codes is None and addresses is None: |
| 193 | + raise ValueError |
| 194 | + path = f"{distance}/{units}" |
| 195 | + dc = MultiRadius |
| 196 | + params = dict() |
| 197 | + if zip_codes: |
| 198 | + params["zip_codes"] = "\n".join(zip_codes) |
| 199 | + if addresses: |
| 200 | + params["addrs"] = "\n".join(addresses) |
| 201 | + body = urlencode(params) |
| 202 | + return self._api_call("multi-radius", f, path, dc, method="POST", body=body) |
0 commit comments