parseapi 0.3.2__tar.gz → 1.0.0__tar.gz

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.
@@ -0,0 +1,291 @@
1
+ Metadata-Version: 2.5
2
+ Name: parseapi
3
+ Version: 1.0.0
4
+ Summary: Official ParseAPI client for Python. One key, minimal JSON, fast.
5
+ Project-URL: Homepage, https://parseapi.com
6
+ Project-URL: Documentation, https://parseapi.com/docs
7
+ Project-URL: Repository, https://github.com/parseapi/python
8
+ Author-email: ParseAPI <hello@parseapi.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: currency,email validation,geolocation,ip,parseapi,phone validation,postal,timezone,weather
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Software Development :: Libraries
16
+ Requires-Python: >=3.9
17
+ Requires-Dist: httpx>=0.24
18
+ Description-Content-Type: text/markdown
19
+
20
+ # parseapi
21
+
22
+ Official ParseAPI client for Python.
23
+
24
+ ```bash
25
+ pip install parseapi
26
+ ```
27
+
28
+ ```python
29
+ from parseapi import ParseAPI
30
+
31
+ parse = ParseAPI("your-api-key")
32
+ country = parse.country("US")
33
+ ```
34
+
35
+ Get a key at [parseapi.com](https://parseapi.com). The client also reads `PARSEAPI_KEY` from the environment.
36
+
37
+ ## API versions
38
+
39
+ Version 1.0.0 explicitly selects the API contract supported by this SDK. It sends `Parse-Version: 2.0.0` on every lookup so responses match the API contract supported by the package. Your key and the team's saved default stay the same.
40
+
41
+ Upgrade the dependency in staging, review the [release notes](https://parseapi.com/docs/releases), and test the application before deploying the same code and dependency version to production. Commit your dependency lockfile so the tested package travels with your deployment. Future major SDK upgrades can select a newer API contract.
42
+
43
+ Previously published SDKs keep their existing behavior and use the team's default. Requests without `Parse-Version` also use that default, managed in [Dashboard API version](https://parseapi.com/dashboard/versions). Keep it unchanged while older applications depend on it. Rolling back to an SDK without a version header restores the team default, so rollback only restores the old contract when that default has stayed unchanged.
44
+
45
+ The package owns its supported API version. For direct HTTP integrations, an explicit `Parse-Version` header selects a supported contract. See [API versions and migration](https://parseapi.com/docs/versioning).
46
+
47
+ ## Weather from a postal code
48
+
49
+ Start with the postal code, then pass its coordinates to weather. Reuse the client from the example above.
50
+
51
+ ```python
52
+ place = parse.postal("28202", country="US")
53
+ lat, lon = place["latitude"], place["longitude"]
54
+ if lat is not None and lon is not None:
55
+ weather = parse.weather(lat, lon)
56
+ print(weather)
57
+ ```
58
+
59
+ The coordinates represent the postal area. Weather is for that point. Missing coordinates skip the weather lookup. This composition performs two ordinary lookups when coordinates are available, with the retry policy below.
60
+
61
+ ## Supply the context you know
62
+
63
+ Pass `country` when a postal code or national phone number needs disambiguation. A complete international phone number already carries its country context. For a numeric date such as `03/04/2026`, supply the intended `format`. Defaults resolve what the input establishes. Ambiguous input needs your context.
64
+
65
+ Results are plain data. Pass a returned code or coordinate to another operation when the task needs it. Check nullable values before composing the next call.
66
+
67
+ Use `parse.postal("28202", country="US", deep=True)` for US ZIP tax references. `deep.tax` names the levy and `deep.tax_rate` is a percentage, so `7.9` means 7.9%. The state, county, city and special components explain that combined rate. An exact address can differ. Country and state lookups provide their own geographic reference rates, which should not be added to the ZIP rate. `None` means unknown and `0` means known zero. Country `deep.tax_id_format` and `deep.tax_id_regex` describe registration-number format only. Use `vat` for a metered registration check with `deep` explicitly enabled.
68
+
69
+ ## Calls
70
+
71
+ One method per endpoint, named after the route.
72
+
73
+ ```python
74
+ parse.ip("8.8.8.8")
75
+ parse.ip.self()
76
+ parse.email("hello@gmail.com")
77
+ parse.vat("DE136695976")
78
+ parse.iban("DE89370400440532013000")
79
+ parse.bin("424242")
80
+ parse.npi("1881018208")
81
+ parse.phone("+14155552671")
82
+ parse.carrier("+14155552671")
83
+ parse.caller("+14155552671")
84
+ parse.hlr("+14155552671")
85
+ parse.postal("SW1A 1AA")
86
+ parse.postal("28202", country="US")
87
+ parse.postal.nearby("28202", country="US", radius=40)
88
+ parse.postal.distance("28202", "10001", country="US")
89
+ parse.address("1600 Pennsylvania Ave NW, Washington DC", country="US")
90
+ parse.address.search("1600 Pennsylvania", country="US", postal="20500")
91
+ parse.company("51 824 753 556", country="AU")
92
+ parse.city("charlotte", country="US")
93
+ parse.city.id("city_mb8mbqrkz8zb")
94
+ parse.city.search("char", country="US", limit=10)
95
+ parse.city.nearest(35.2271, -80.8431)
96
+ parse.city.nearby("denver", radius=8, unit="mi")
97
+ parse.country("US")
98
+ parse.country.states("US")
99
+ parse.state("colorado")
100
+ parse.state("NC", country="US")
101
+ parse.state.districts("NC", country="US")
102
+ parse.district("37081")
103
+ parse.continent("NA")
104
+ parse.continent.countries("NA")
105
+ parse.bloc("EU")
106
+ parse.bloc.countries("EU")
107
+ parse.currency("USD")
108
+ parse.currency.rate("USD", "EUR")
109
+ parse.language("en")
110
+ parse.name("BILLY OSHALL")
111
+ parse.name("Andrea", country="IT", deep=True)
112
+ parse.name("Robert James Smith", deep=True, name_locale="en")
113
+ parse.time() # UTC now
114
+ parse.time("America/New_York")
115
+ parse.time("America/New_York", at="2026-09-05T15:00:00", to="Europe/London")
116
+ parse.time.at(39.77, -104.9)
117
+ parse.date("03/04/2026", format="mdy")
118
+ parse.date.today()
119
+ parse.holiday("US", year=2026)
120
+ parse.holiday.date("US", "2026-12-25")
121
+ parse.elevation(35.2271, -80.8431)
122
+ parse.point(36.0726, -79.792)
123
+ parse.weather(40.7128, -74.006)
124
+ parse.domain("example.com")
125
+ parse.asn("AS13335")
126
+ parse.mac("00:1B:63:84:45:E6")
127
+ parse.mx("example.com")
128
+ parse.dns("example.com")
129
+ parse.dns("_dmarc.example.com", type="TXT")
130
+ parse.useragent(ua_string)
131
+ parse.vin("1HGCM82633A004352")
132
+ parse.naics("541511")
133
+ parse.naics.search("coffee shop", limit=5)
134
+ parse.tariff("8471.30.01.00")
135
+ parse.tariff.search("sunglasses")
136
+ parse.emoji("rocket")
137
+ parse.emoji.search("fire")
138
+ ```
139
+
140
+ NAICS paid deep records include classification `deep.exclusions`, each with a description and linked codes. Generic exclusions can have no linked codes. Omitted or null exclusions in older responses remain unknown. Search results also include `match`: the matched `field` (`name`, `term` or `naics`) and `text`, plus `corrections` with `from` and `to` tokens for typo fallback. Corrections are empty for exact, plural and prefix matches. Direct code lookups omit `match`. Older responses may omit it.
141
+
142
+ Responses are plain dicts, exactly the JSON the API returns. `country.states("US")` requests states directly; it does not fetch a country first. Required inputs are positional and optional behavior uses keyword arguments, leaving room for new options without changing existing calls. Reuse a client across calls. Use `with ParseAPI(...) as parse:` or call `parse.close()` when finished.
143
+
144
+ DNS uses pooled requests on every plan. Omit `type` to check A, AAAA, CNAME, MX, NS, TXT, SOA, CAA, SRV and PTR. Records contain `name`, `type`, `ttl` in seconds and a DNS presentation `value`. TXT values retain quoting and chunk boundaries. A selected question can include its CNAME chain. Empty records mean no records. Lookup failures remain errors.
145
+
146
+ ## Async
147
+
148
+ Same lookup methods and keyword arguments, with `await`. Use a context manager to close the client when the work is done.
149
+
150
+ ```python
151
+ from parseapi import AsyncParseAPI
152
+
153
+ async with AsyncParseAPI("your-api-key") as parse:
154
+ country = await parse.country("US")
155
+ ```
156
+
157
+ Name paid deep includes flat `short`, `directory`, and `initials` fields beside `gender` and `salutation`. `name_locale` selects CLDR formatting rules and defaults to `en`. It changes formatting only. Country remains gender context, and unavailable formatting is null. Older responses may omit these fields.
158
+
159
+ ## Display language
160
+
161
+ Choose display names for one request:
162
+
163
+ ```python
164
+ parse.country("DE", lang="fr")
165
+ ```
166
+
167
+ `lang` is optional on geography lookups and their lists/searches, Currency lookup, Language, Date, Time/Timezone, Emoji lookup/search, and unit discovery. IP, ASN, Company and NPI also accept it for their geographic labels. Codes, native names, quantities and response structure retain their meanings. Source coverage determines which labels are translated; unavailable labels use the API's documented fallback.
168
+
169
+ The next call keeps its usual default unless it also supplies `lang`. Existing `deep` rules still apply. Date `format` and measurement `locale` remain explicit input-parsing controls.
170
+
171
+ ## Time
172
+
173
+ `time` returns local ISO `at` with its UTC offset and integer Unix seconds in `unix`. The core `offset` preserves exact precision. Optional `deep.offset_seconds` gives the numeric offset, while `deep.offset_minutes` gives whole minutes. Historical offsets and ISO times can include offset seconds. Omitted `at` means now. With `to`, an offsetless `at` is source wall time. Otherwise it is UTC. Include an offset for repeated local times around a clock change. Current time and conversion use pooled requests on every plan. Coordinate clock fields can be null when the timezone is unknown. Existing `timezone` methods remain supported.
174
+
175
+ ## Measurements
176
+
177
+ ```python
178
+ result = parse.measure("5 ft 11 in", to="cm")
179
+ units = parse.measure.units(unit="m")
180
+ ```
181
+
182
+ `amount` is a decimal string, such as `"180.34"`. Without `to`, the API returns the canonical unit for the measurement type. Pass `locale` for number formatting and `system` (`us` or `imperial`) when a customary unit needs context. Ambiguous input returns `valid: false`, a `reason`, and available `choices`. Invalid or incompatible target units use the normal API error.
183
+
184
+ Unit discovery accepts optional `query`, `type`, and `unit` filters. `unit` selects compatible targets. Omit the filters for the reviewed catalog. Both operations use pooled requests.
185
+
186
+ ## Place statistics and optional detail
187
+
188
+ Postal and District paid profiles include `deep.property_tax` where supported. It contains `annual_median`, `currency` and `period`: median annual property tax payable on owner-occupied homes in the statistical area. The amount is adjusted to the final year of the reporting period (`YYYY-YYYY`). This is an area statistic, not a rate or an individual property bill. Unsupported, missing and censored estimates are null.
189
+
190
+ ```python
191
+ place = parse.postal("28202", country="US", deep=True)
192
+ property_tax = (place.get("deep") or {}).get("property_tax")
193
+ ```
194
+
195
+ Read `population_period` alongside `population`: a reporting year (`YYYY`) or period (`YYYY-YYYY`), null when unknown or unverifiable. Keep missing or null values unknown and preserve a known zero. These fields belong to full place profiles. State district lists include each district's population and period. Postal nearby and distance detail remains metropolitan associations only. Continent population stays in core.
196
+
197
+ Country deep includes `land_area` and `water_area` in km2, `coastline` in km, and mean `elevation` in metres. `lowest_point` and `highest_point` contain a nullable `name` and an `elevation` in metres. Values below sea level are negative. Missing or null values stay unknown, and zero stays zero.
198
+
199
+ Point returns the timezone ID with the core location. Its optional deep detail adds terrain and compact nearest-city context on every plan. A nearest city is null when none is within 200 km.
200
+
201
+ Weather returns current conditions by default. Paid deep adds specialist current measurements, forecasts and related detail. A past `date` is a UTC day and requires deep: it adds `deep.history` alongside current conditions. Date alone does not request history.
202
+
203
+ ```python
204
+ parse.weather(40.7128, -74.006, deep=True, date="2026-08-15")
205
+ ```
206
+
207
+ Tariff starts with the general schedule line. Paid deep adds units and the special and other schedule columns. An optional origin then resolves country-specific measures. The three calls below show those successive choices. Without origin, schedule detail is still returned and origin-dependent fields are null. A null effective rate is not a zero rate.
208
+
209
+ ```python
210
+ parse.tariff("8471.30.01.00")
211
+ parse.tariff("8471.30.01.00", deep=True)
212
+ parse.tariff("8471.30.01.00", deep=True, origin="CN")
213
+ ```
214
+
215
+ Address search uses context from the form: prefer postal, or city and state. An optional end-user `ip` is a locality hint for server-side calls. An empty result explains itself with `reason`: `more_input`, `missing_context` or `no_matches`. With suggestions, reason is null. Older responses may omit it, and future reasons remain strings. Catalog and lookup failures use the existing API errors.
216
+
217
+ HLR reports status at the last check. `live` means assigned and `connected` means reachable at that check. Cached results may be returned. Null means unconfirmed. Deep diagnostics stay within the same metered lookup.
218
+
219
+ ## Deep
220
+
221
+ Choose enrichment for the question you need answered.
222
+
223
+ | Operation | What `deep` requests |
224
+ |---|---|
225
+ | IP | Richer IP fields included with a paid plan. No separate check meter. |
226
+ | Domain | Registration dates, registrar, status and DNSSEC, included with a paid plan. Use `dns` for DNS records and `mx` for mail routing. |
227
+ | Email | A metered deliverability check, using included email checks or enabled on-demand usage. |
228
+ | VAT | A metered registry check where supported, using included VAT checks or enabled on-demand usage. |
229
+ | Phone, Time, Date, Currency, Language, Emoji, IBAN, Point | Optional detail in the same pooled request on every plan. |
230
+ | Country, State, District, City, Postal | The place profile on paid plans, including demographic and tax facts where held. |
231
+ | Name, NAICS | Name evidence or the industry definition profile on paid plans. |
232
+ | VIN, NPI, Tariff, Company | The complete product detail bag on paid plans. |
233
+ | Weather | Specialist current measurements and the existing forecast, alert, air and history bag on paid plans. |
234
+ | Carrier, HLR | Optional diagnostic detail within the same metered core unit, including Free allowance units. No second gate or additional check. |
235
+
236
+ Carrier, caller, and HLR are separate metered operations. Choose them explicitly when you need their answers. Ordinary lookups retry twice by default. Metered checks use one attempt by default. Setting retries explicitly can repeat paid usage.
237
+
238
+ Without `deep`, the response omits that key. When requested, it is an empty object if access is locked or the operation has no deep fields. Otherwise it contains the available fields. A missing or null field means unknown.
239
+
240
+ ```python
241
+ ip = parse.ip("52.94.76.10", deep=True)
242
+ ip.get("deep", {}).get("datacenter") # True, False, or None
243
+ ```
244
+
245
+ ## Errors
246
+
247
+ Every non-2xx response raises `ParseAPIError` with `status`, `code`, `docs`, and `request_id`. Branch on `code`.
248
+
249
+ ```python
250
+ from parseapi import ParseAPIError
251
+
252
+ try:
253
+ parse.city("atlantis")
254
+ except ParseAPIError as err:
255
+ if err.code == "not_found":
256
+ ... # no such city
257
+ ```
258
+
259
+ Network and decoding failures keep their native error types. Responses such as `valid: false` are successful API answers, not exceptions.
260
+
261
+ ## Options
262
+
263
+ ```python
264
+ parse = ParseAPI(
265
+ "your-api-key",
266
+ timeout=10.0, # timeout for each connect, read, write, or pool phase
267
+ )
268
+ ```
269
+
270
+ Requires Python 3.9 or later. One dependency (httpx).
271
+
272
+ Ordinary lookups retry network failures, 429, and 500/502/503/504 responses twice by default. Carrier, caller, HLR, and email or VAT with `deep=True` make one attempt by default. Address with `deep=True` also uses one attempt, reserving the same behavior for future verification.
273
+
274
+ An explicit client `retries` setting overrides those defaults; `retries=0` always makes one attempt. Another attempt can consume additional usage if the earlier response was lost. Cancelling an async task stops the call and any retry wait. Automatic redirects are disabled.
275
+
276
+ ## Docs
277
+
278
+ Full field reference for every endpoint: [parseapi.com/docs](https://parseapi.com/docs)
279
+
280
+ BIN lookup accepts 6-11 digits as a string, including leading zeros. Spaces and hyphens are accepted. `prefix` is the actual longest match and can be shorter than the input. Unknown reference fields are null. `deep` adds an empty object on every plan.
281
+
282
+
283
+ ## Optional detail
284
+
285
+ The default response answers the common task. Ask for `deep` when you need more detail about that same result. Core fields stay equal. City, NAICS and Emoji searches put detail inside each result. Postal nearby and distance put metropolitan detail beside the entity it describes. Time conversion keeps target detail in `to.deep`; only the source has `deep.next_dst`.
286
+
287
+ ```python
288
+ basic = parse.time("America/New_York")
289
+ detail = parse.time("America/New_York", deep=True)
290
+ print(basic["at"], detail.get("deep", {}).get("next_dst"))
291
+ ```
@@ -0,0 +1,272 @@
1
+ # parseapi
2
+
3
+ Official ParseAPI client for Python.
4
+
5
+ ```bash
6
+ pip install parseapi
7
+ ```
8
+
9
+ ```python
10
+ from parseapi import ParseAPI
11
+
12
+ parse = ParseAPI("your-api-key")
13
+ country = parse.country("US")
14
+ ```
15
+
16
+ Get a key at [parseapi.com](https://parseapi.com). The client also reads `PARSEAPI_KEY` from the environment.
17
+
18
+ ## API versions
19
+
20
+ Version 1.0.0 explicitly selects the API contract supported by this SDK. It sends `Parse-Version: 2.0.0` on every lookup so responses match the API contract supported by the package. Your key and the team's saved default stay the same.
21
+
22
+ Upgrade the dependency in staging, review the [release notes](https://parseapi.com/docs/releases), and test the application before deploying the same code and dependency version to production. Commit your dependency lockfile so the tested package travels with your deployment. Future major SDK upgrades can select a newer API contract.
23
+
24
+ Previously published SDKs keep their existing behavior and use the team's default. Requests without `Parse-Version` also use that default, managed in [Dashboard API version](https://parseapi.com/dashboard/versions). Keep it unchanged while older applications depend on it. Rolling back to an SDK without a version header restores the team default, so rollback only restores the old contract when that default has stayed unchanged.
25
+
26
+ The package owns its supported API version. For direct HTTP integrations, an explicit `Parse-Version` header selects a supported contract. See [API versions and migration](https://parseapi.com/docs/versioning).
27
+
28
+ ## Weather from a postal code
29
+
30
+ Start with the postal code, then pass its coordinates to weather. Reuse the client from the example above.
31
+
32
+ ```python
33
+ place = parse.postal("28202", country="US")
34
+ lat, lon = place["latitude"], place["longitude"]
35
+ if lat is not None and lon is not None:
36
+ weather = parse.weather(lat, lon)
37
+ print(weather)
38
+ ```
39
+
40
+ The coordinates represent the postal area. Weather is for that point. Missing coordinates skip the weather lookup. This composition performs two ordinary lookups when coordinates are available, with the retry policy below.
41
+
42
+ ## Supply the context you know
43
+
44
+ Pass `country` when a postal code or national phone number needs disambiguation. A complete international phone number already carries its country context. For a numeric date such as `03/04/2026`, supply the intended `format`. Defaults resolve what the input establishes. Ambiguous input needs your context.
45
+
46
+ Results are plain data. Pass a returned code or coordinate to another operation when the task needs it. Check nullable values before composing the next call.
47
+
48
+ Use `parse.postal("28202", country="US", deep=True)` for US ZIP tax references. `deep.tax` names the levy and `deep.tax_rate` is a percentage, so `7.9` means 7.9%. The state, county, city and special components explain that combined rate. An exact address can differ. Country and state lookups provide their own geographic reference rates, which should not be added to the ZIP rate. `None` means unknown and `0` means known zero. Country `deep.tax_id_format` and `deep.tax_id_regex` describe registration-number format only. Use `vat` for a metered registration check with `deep` explicitly enabled.
49
+
50
+ ## Calls
51
+
52
+ One method per endpoint, named after the route.
53
+
54
+ ```python
55
+ parse.ip("8.8.8.8")
56
+ parse.ip.self()
57
+ parse.email("hello@gmail.com")
58
+ parse.vat("DE136695976")
59
+ parse.iban("DE89370400440532013000")
60
+ parse.bin("424242")
61
+ parse.npi("1881018208")
62
+ parse.phone("+14155552671")
63
+ parse.carrier("+14155552671")
64
+ parse.caller("+14155552671")
65
+ parse.hlr("+14155552671")
66
+ parse.postal("SW1A 1AA")
67
+ parse.postal("28202", country="US")
68
+ parse.postal.nearby("28202", country="US", radius=40)
69
+ parse.postal.distance("28202", "10001", country="US")
70
+ parse.address("1600 Pennsylvania Ave NW, Washington DC", country="US")
71
+ parse.address.search("1600 Pennsylvania", country="US", postal="20500")
72
+ parse.company("51 824 753 556", country="AU")
73
+ parse.city("charlotte", country="US")
74
+ parse.city.id("city_mb8mbqrkz8zb")
75
+ parse.city.search("char", country="US", limit=10)
76
+ parse.city.nearest(35.2271, -80.8431)
77
+ parse.city.nearby("denver", radius=8, unit="mi")
78
+ parse.country("US")
79
+ parse.country.states("US")
80
+ parse.state("colorado")
81
+ parse.state("NC", country="US")
82
+ parse.state.districts("NC", country="US")
83
+ parse.district("37081")
84
+ parse.continent("NA")
85
+ parse.continent.countries("NA")
86
+ parse.bloc("EU")
87
+ parse.bloc.countries("EU")
88
+ parse.currency("USD")
89
+ parse.currency.rate("USD", "EUR")
90
+ parse.language("en")
91
+ parse.name("BILLY OSHALL")
92
+ parse.name("Andrea", country="IT", deep=True)
93
+ parse.name("Robert James Smith", deep=True, name_locale="en")
94
+ parse.time() # UTC now
95
+ parse.time("America/New_York")
96
+ parse.time("America/New_York", at="2026-09-05T15:00:00", to="Europe/London")
97
+ parse.time.at(39.77, -104.9)
98
+ parse.date("03/04/2026", format="mdy")
99
+ parse.date.today()
100
+ parse.holiday("US", year=2026)
101
+ parse.holiday.date("US", "2026-12-25")
102
+ parse.elevation(35.2271, -80.8431)
103
+ parse.point(36.0726, -79.792)
104
+ parse.weather(40.7128, -74.006)
105
+ parse.domain("example.com")
106
+ parse.asn("AS13335")
107
+ parse.mac("00:1B:63:84:45:E6")
108
+ parse.mx("example.com")
109
+ parse.dns("example.com")
110
+ parse.dns("_dmarc.example.com", type="TXT")
111
+ parse.useragent(ua_string)
112
+ parse.vin("1HGCM82633A004352")
113
+ parse.naics("541511")
114
+ parse.naics.search("coffee shop", limit=5)
115
+ parse.tariff("8471.30.01.00")
116
+ parse.tariff.search("sunglasses")
117
+ parse.emoji("rocket")
118
+ parse.emoji.search("fire")
119
+ ```
120
+
121
+ NAICS paid deep records include classification `deep.exclusions`, each with a description and linked codes. Generic exclusions can have no linked codes. Omitted or null exclusions in older responses remain unknown. Search results also include `match`: the matched `field` (`name`, `term` or `naics`) and `text`, plus `corrections` with `from` and `to` tokens for typo fallback. Corrections are empty for exact, plural and prefix matches. Direct code lookups omit `match`. Older responses may omit it.
122
+
123
+ Responses are plain dicts, exactly the JSON the API returns. `country.states("US")` requests states directly; it does not fetch a country first. Required inputs are positional and optional behavior uses keyword arguments, leaving room for new options without changing existing calls. Reuse a client across calls. Use `with ParseAPI(...) as parse:` or call `parse.close()` when finished.
124
+
125
+ DNS uses pooled requests on every plan. Omit `type` to check A, AAAA, CNAME, MX, NS, TXT, SOA, CAA, SRV and PTR. Records contain `name`, `type`, `ttl` in seconds and a DNS presentation `value`. TXT values retain quoting and chunk boundaries. A selected question can include its CNAME chain. Empty records mean no records. Lookup failures remain errors.
126
+
127
+ ## Async
128
+
129
+ Same lookup methods and keyword arguments, with `await`. Use a context manager to close the client when the work is done.
130
+
131
+ ```python
132
+ from parseapi import AsyncParseAPI
133
+
134
+ async with AsyncParseAPI("your-api-key") as parse:
135
+ country = await parse.country("US")
136
+ ```
137
+
138
+ Name paid deep includes flat `short`, `directory`, and `initials` fields beside `gender` and `salutation`. `name_locale` selects CLDR formatting rules and defaults to `en`. It changes formatting only. Country remains gender context, and unavailable formatting is null. Older responses may omit these fields.
139
+
140
+ ## Display language
141
+
142
+ Choose display names for one request:
143
+
144
+ ```python
145
+ parse.country("DE", lang="fr")
146
+ ```
147
+
148
+ `lang` is optional on geography lookups and their lists/searches, Currency lookup, Language, Date, Time/Timezone, Emoji lookup/search, and unit discovery. IP, ASN, Company and NPI also accept it for their geographic labels. Codes, native names, quantities and response structure retain their meanings. Source coverage determines which labels are translated; unavailable labels use the API's documented fallback.
149
+
150
+ The next call keeps its usual default unless it also supplies `lang`. Existing `deep` rules still apply. Date `format` and measurement `locale` remain explicit input-parsing controls.
151
+
152
+ ## Time
153
+
154
+ `time` returns local ISO `at` with its UTC offset and integer Unix seconds in `unix`. The core `offset` preserves exact precision. Optional `deep.offset_seconds` gives the numeric offset, while `deep.offset_minutes` gives whole minutes. Historical offsets and ISO times can include offset seconds. Omitted `at` means now. With `to`, an offsetless `at` is source wall time. Otherwise it is UTC. Include an offset for repeated local times around a clock change. Current time and conversion use pooled requests on every plan. Coordinate clock fields can be null when the timezone is unknown. Existing `timezone` methods remain supported.
155
+
156
+ ## Measurements
157
+
158
+ ```python
159
+ result = parse.measure("5 ft 11 in", to="cm")
160
+ units = parse.measure.units(unit="m")
161
+ ```
162
+
163
+ `amount` is a decimal string, such as `"180.34"`. Without `to`, the API returns the canonical unit for the measurement type. Pass `locale` for number formatting and `system` (`us` or `imperial`) when a customary unit needs context. Ambiguous input returns `valid: false`, a `reason`, and available `choices`. Invalid or incompatible target units use the normal API error.
164
+
165
+ Unit discovery accepts optional `query`, `type`, and `unit` filters. `unit` selects compatible targets. Omit the filters for the reviewed catalog. Both operations use pooled requests.
166
+
167
+ ## Place statistics and optional detail
168
+
169
+ Postal and District paid profiles include `deep.property_tax` where supported. It contains `annual_median`, `currency` and `period`: median annual property tax payable on owner-occupied homes in the statistical area. The amount is adjusted to the final year of the reporting period (`YYYY-YYYY`). This is an area statistic, not a rate or an individual property bill. Unsupported, missing and censored estimates are null.
170
+
171
+ ```python
172
+ place = parse.postal("28202", country="US", deep=True)
173
+ property_tax = (place.get("deep") or {}).get("property_tax")
174
+ ```
175
+
176
+ Read `population_period` alongside `population`: a reporting year (`YYYY`) or period (`YYYY-YYYY`), null when unknown or unverifiable. Keep missing or null values unknown and preserve a known zero. These fields belong to full place profiles. State district lists include each district's population and period. Postal nearby and distance detail remains metropolitan associations only. Continent population stays in core.
177
+
178
+ Country deep includes `land_area` and `water_area` in km2, `coastline` in km, and mean `elevation` in metres. `lowest_point` and `highest_point` contain a nullable `name` and an `elevation` in metres. Values below sea level are negative. Missing or null values stay unknown, and zero stays zero.
179
+
180
+ Point returns the timezone ID with the core location. Its optional deep detail adds terrain and compact nearest-city context on every plan. A nearest city is null when none is within 200 km.
181
+
182
+ Weather returns current conditions by default. Paid deep adds specialist current measurements, forecasts and related detail. A past `date` is a UTC day and requires deep: it adds `deep.history` alongside current conditions. Date alone does not request history.
183
+
184
+ ```python
185
+ parse.weather(40.7128, -74.006, deep=True, date="2026-08-15")
186
+ ```
187
+
188
+ Tariff starts with the general schedule line. Paid deep adds units and the special and other schedule columns. An optional origin then resolves country-specific measures. The three calls below show those successive choices. Without origin, schedule detail is still returned and origin-dependent fields are null. A null effective rate is not a zero rate.
189
+
190
+ ```python
191
+ parse.tariff("8471.30.01.00")
192
+ parse.tariff("8471.30.01.00", deep=True)
193
+ parse.tariff("8471.30.01.00", deep=True, origin="CN")
194
+ ```
195
+
196
+ Address search uses context from the form: prefer postal, or city and state. An optional end-user `ip` is a locality hint for server-side calls. An empty result explains itself with `reason`: `more_input`, `missing_context` or `no_matches`. With suggestions, reason is null. Older responses may omit it, and future reasons remain strings. Catalog and lookup failures use the existing API errors.
197
+
198
+ HLR reports status at the last check. `live` means assigned and `connected` means reachable at that check. Cached results may be returned. Null means unconfirmed. Deep diagnostics stay within the same metered lookup.
199
+
200
+ ## Deep
201
+
202
+ Choose enrichment for the question you need answered.
203
+
204
+ | Operation | What `deep` requests |
205
+ |---|---|
206
+ | IP | Richer IP fields included with a paid plan. No separate check meter. |
207
+ | Domain | Registration dates, registrar, status and DNSSEC, included with a paid plan. Use `dns` for DNS records and `mx` for mail routing. |
208
+ | Email | A metered deliverability check, using included email checks or enabled on-demand usage. |
209
+ | VAT | A metered registry check where supported, using included VAT checks or enabled on-demand usage. |
210
+ | Phone, Time, Date, Currency, Language, Emoji, IBAN, Point | Optional detail in the same pooled request on every plan. |
211
+ | Country, State, District, City, Postal | The place profile on paid plans, including demographic and tax facts where held. |
212
+ | Name, NAICS | Name evidence or the industry definition profile on paid plans. |
213
+ | VIN, NPI, Tariff, Company | The complete product detail bag on paid plans. |
214
+ | Weather | Specialist current measurements and the existing forecast, alert, air and history bag on paid plans. |
215
+ | Carrier, HLR | Optional diagnostic detail within the same metered core unit, including Free allowance units. No second gate or additional check. |
216
+
217
+ Carrier, caller, and HLR are separate metered operations. Choose them explicitly when you need their answers. Ordinary lookups retry twice by default. Metered checks use one attempt by default. Setting retries explicitly can repeat paid usage.
218
+
219
+ Without `deep`, the response omits that key. When requested, it is an empty object if access is locked or the operation has no deep fields. Otherwise it contains the available fields. A missing or null field means unknown.
220
+
221
+ ```python
222
+ ip = parse.ip("52.94.76.10", deep=True)
223
+ ip.get("deep", {}).get("datacenter") # True, False, or None
224
+ ```
225
+
226
+ ## Errors
227
+
228
+ Every non-2xx response raises `ParseAPIError` with `status`, `code`, `docs`, and `request_id`. Branch on `code`.
229
+
230
+ ```python
231
+ from parseapi import ParseAPIError
232
+
233
+ try:
234
+ parse.city("atlantis")
235
+ except ParseAPIError as err:
236
+ if err.code == "not_found":
237
+ ... # no such city
238
+ ```
239
+
240
+ Network and decoding failures keep their native error types. Responses such as `valid: false` are successful API answers, not exceptions.
241
+
242
+ ## Options
243
+
244
+ ```python
245
+ parse = ParseAPI(
246
+ "your-api-key",
247
+ timeout=10.0, # timeout for each connect, read, write, or pool phase
248
+ )
249
+ ```
250
+
251
+ Requires Python 3.9 or later. One dependency (httpx).
252
+
253
+ Ordinary lookups retry network failures, 429, and 500/502/503/504 responses twice by default. Carrier, caller, HLR, and email or VAT with `deep=True` make one attempt by default. Address with `deep=True` also uses one attempt, reserving the same behavior for future verification.
254
+
255
+ An explicit client `retries` setting overrides those defaults; `retries=0` always makes one attempt. Another attempt can consume additional usage if the earlier response was lost. Cancelling an async task stops the call and any retry wait. Automatic redirects are disabled.
256
+
257
+ ## Docs
258
+
259
+ Full field reference for every endpoint: [parseapi.com/docs](https://parseapi.com/docs)
260
+
261
+ BIN lookup accepts 6-11 digits as a string, including leading zeros. Spaces and hyphens are accepted. `prefix` is the actual longest match and can be shorter than the input. Unknown reference fields are null. `deep` adds an empty object on every plan.
262
+
263
+
264
+ ## Optional detail
265
+
266
+ The default response answers the common task. Ask for `deep` when you need more detail about that same result. Core fields stay equal. City, NAICS and Emoji searches put detail inside each result. Postal nearby and distance put metropolitan detail beside the entity it describes. Time conversion keeps target detail in `to.deep`; only the source has `deep.next_dst`.
267
+
268
+ ```python
269
+ basic = parse.time("America/New_York")
270
+ detail = parse.time("America/New_York", deep=True)
271
+ print(basic["at"], detail.get("deep", {}).get("next_dst"))
272
+ ```