internetdata 1.2.2__tar.gz → 2.1.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.
Files changed (58) hide show
  1. {internetdata-1.2.2 → internetdata-2.1.0}/PKG-INFO +9 -1
  2. {internetdata-1.2.2 → internetdata-2.1.0}/README.md +8 -0
  3. {internetdata-1.2.2 → internetdata-2.1.0}/spec/openapi.yaml +23 -23
  4. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/__init__.py +1 -1
  5. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_core.py +131 -5
  6. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/api/database_v_2/database_checksum_v2.py +10 -10
  7. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/api/database_v_2/download_database_v2.py +10 -10
  8. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/__init__.py +4 -10
  9. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/database.py +7 -6
  10. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/database_checksum_v2_response_200.py +4 -4
  11. internetdata-1.2.2/src/internetdata/_generated/models/download_database_v2_format.py → internetdata-2.1.0/src/internetdata/_generated/models/database_format.py +1 -1
  12. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/database_version.py +4 -4
  13. internetdata-1.2.2/src/internetdata/_generated/models/database_standing.py → internetdata-2.1.0/src/internetdata/_generated/models/standing.py +1 -1
  14. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/aio.py +20 -20
  15. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/client.py +22 -20
  16. {internetdata-1.2.2 → internetdata-2.1.0}/tests/helpers.py +138 -1
  17. {internetdata-1.2.2 → internetdata-2.1.0}/tests/test_client.py +114 -1
  18. {internetdata-1.2.2 → internetdata-2.1.0}/tests/test_download.py +82 -6
  19. internetdata-1.2.2/src/internetdata/_generated/models/database_checksum_v2_format.py +0 -9
  20. internetdata-1.2.2/src/internetdata/_generated/models/database_checksum_v2_response_200_format.py +0 -9
  21. internetdata-1.2.2/src/internetdata/_generated/models/database_version_formats_item.py +0 -9
  22. {internetdata-1.2.2 → internetdata-2.1.0}/.gitignore +0 -0
  23. {internetdata-1.2.2 → internetdata-2.1.0}/LICENSE +0 -0
  24. {internetdata-1.2.2 → internetdata-2.1.0}/pyproject.toml +0 -0
  25. {internetdata-1.2.2 → internetdata-2.1.0}/scripts/download-spec.sh +0 -0
  26. {internetdata-1.2.2 → internetdata-2.1.0}/scripts/generate.sh +0 -0
  27. {internetdata-1.2.2 → internetdata-2.1.0}/scripts/publish.sh +0 -0
  28. {internetdata-1.2.2 → internetdata-2.1.0}/scripts/v2_subset.py +0 -0
  29. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/__init__.py +0 -0
  30. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/api/__init__.py +0 -0
  31. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/api/database_v_2/__init__.py +0 -0
  32. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/api/database_v_2/database_metadata_v2.py +0 -0
  33. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/api/database_v_2/list_databases.py +0 -0
  34. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/api/database_v_2/list_downloads.py +0 -0
  35. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/client.py +0 -0
  36. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/errors.py +0 -0
  37. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/database_license_type_type_1.py +0 -0
  38. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/database_license_type_type_2_type_1.py +0 -0
  39. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/database_license_type_type_3_type_1.py +0 -0
  40. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/database_metadata.py +0 -0
  41. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/database_metadata_column.py +0 -0
  42. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/database_metadata_sample.py +0 -0
  43. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/database_metadata_sample_additional_property_item.py +0 -0
  44. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/database_metadata_schema.py +0 -0
  45. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/database_metadata_size.py +0 -0
  46. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/db_checksums.py +0 -0
  47. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/download.py +0 -0
  48. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/download_outcome.py +0 -0
  49. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/error.py +0 -0
  50. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/list_databases_response_200.py +0 -0
  51. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/models/list_downloads_response_200.py +0 -0
  52. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/_generated/types.py +0 -0
  53. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/errors.py +0 -0
  54. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/models.py +0 -0
  55. {internetdata-1.2.2 → internetdata-2.1.0}/src/internetdata/py.typed +0 -0
  56. {internetdata-1.2.2 → internetdata-2.1.0}/testdata/testdata.json +0 -0
  57. {internetdata-1.2.2 → internetdata-2.1.0}/tests/conftest.py +0 -0
  58. {internetdata-1.2.2 → internetdata-2.1.0}/tests/test_conformance.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: internetdata
3
- Version: 1.2.2
3
+ Version: 2.1.0
4
4
  Summary: Official Python client library for the InternetData API. Download and verify licensed IP datasets.
5
5
  Project-URL: Homepage, https://internetdata.io
6
6
  Project-URL: Documentation, https://docs.internetdata.io
@@ -165,6 +165,14 @@ except InternetDataError as err:
165
165
 
166
166
  `kind` is one of `bad_request`, `unauthorized`, `forbidden`, `rate_limited`, `quota_exceeded`, `server_error` or `network`. `message` is the API's own result code, passed through as it was sent, so you can switch on `NOT_LICENSED` against `LICENSE_EXPIRED` without reading the status.
167
167
 
168
+ A request that runs past its `timeout` fails with `network`, and is retried like any other network failure. The default is 30 seconds per attempt, body included, so a retried call can take longer in total. A database transfer is exempt, so `download` and `download_bytes` are never cut off part way through a large file. Set it on the client, in seconds, or pass `None` for no bound:
169
+
170
+ ```python
171
+ client = InternetData(api_key, timeout=10)
172
+ ```
173
+
174
+ **Changed in 2.1.0:** the default was 10 seconds, and it bounded each read of a response rather than the whole attempt, so a response trickling in slowly could run past it for as long as the server kept sending.
175
+
168
176
  Note that `rate_limited` and `quota_exceeded` both arrive as HTTP 429 and are not the same thing. A rate limit is the API facing a traffic burst, and retrying later works; a spent quota needs your allowance raised or the window to roll over. The library retries rate limits for you, and server and network failures, but never a spent quota or anything else you sent.
169
177
 
170
178
  ## Other Libraries
@@ -131,6 +131,14 @@ except InternetDataError as err:
131
131
 
132
132
  `kind` is one of `bad_request`, `unauthorized`, `forbidden`, `rate_limited`, `quota_exceeded`, `server_error` or `network`. `message` is the API's own result code, passed through as it was sent, so you can switch on `NOT_LICENSED` against `LICENSE_EXPIRED` without reading the status.
133
133
 
134
+ A request that runs past its `timeout` fails with `network`, and is retried like any other network failure. The default is 30 seconds per attempt, body included, so a retried call can take longer in total. A database transfer is exempt, so `download` and `download_bytes` are never cut off part way through a large file. Set it on the client, in seconds, or pass `None` for no bound:
135
+
136
+ ```python
137
+ client = InternetData(api_key, timeout=10)
138
+ ```
139
+
140
+ **Changed in 2.1.0:** the default was 10 seconds, and it bounded each read of a response rather than the whole attempt, so a response trickling in slowly could run past it for as long as the server kept sending.
141
+
134
142
  Note that `rate_limited` and `quota_exceeded` both arrive as HTTP 429 and are not the same thing. A rate limit is the API facing a traffic burst, and retrying later works; a spent quota needs your allowance raised or the window to roll over. The library retries rate limits for you, and server and network failures, but never a spent quota or anything else you sent.
135
143
 
136
144
  ## Other Libraries
@@ -8,7 +8,7 @@ info:
8
8
  email: dev@internetdata.io
9
9
  url: https://internetdata.io
10
10
  termsOfService: https://internetdata.io/terms-of-service/
11
- version: 2026.09.09
11
+ version: 2026.09.13
12
12
  servers:
13
13
  - url: https://internetdata.io
14
14
  security:
@@ -162,10 +162,7 @@ paths:
162
162
  id:
163
163
  type: string
164
164
  format:
165
- type: string
166
- enum:
167
- - csvgz
168
- - mmdb
165
+ $ref: '#/components/schemas/DatabaseFormat'
169
166
  checksums:
170
167
  $ref: '#/components/schemas/DbChecksums'
171
168
  '400':
@@ -362,11 +359,7 @@ components:
362
359
  required: true
363
360
  description: Database file format.
364
361
  schema:
365
- type: string
366
- enum:
367
- - csvgz
368
- - mmdb
369
- example: mmdb
362
+ $ref: '#/components/schemas/DatabaseFormat'
370
363
  schemas:
371
364
  Error:
372
365
  type: object
@@ -378,6 +371,23 @@ components:
378
371
  description: |
379
372
  A machine-readable result code. Deliberately not an enum: a code
380
373
  added later must stay parseable by a client generated today.
374
+ DatabaseFormat:
375
+ type: string
376
+ description: A file format a database version is published in.
377
+ enum:
378
+ - csvgz
379
+ - mmdb
380
+ example: mmdb
381
+ Standing:
382
+ type: string
383
+ description: |
384
+ Where your licence for a database family stands today. `licensed` is a
385
+ live grant, `expired` one whose term has ended, and `unlicensed` a
386
+ database published but never bought.
387
+ enum:
388
+ - licensed
389
+ - expired
390
+ - unlicensed
381
391
  Database:
382
392
  type: object
383
393
  description: |
@@ -407,14 +417,7 @@ components:
407
417
  type: string
408
418
  description: One line on what the newest version contains.
409
419
  standing:
410
- type: string
411
- enum:
412
- - licensed
413
- - expired
414
- - unlicensed
415
- description: |
416
- `licensed` is a live grant, `expired` one whose term has ended, and
417
- `unlicensed` a database published but never bought.
420
+ $ref: '#/components/schemas/Standing'
418
421
  license_type:
419
422
  type: string
420
423
  nullable: true
@@ -425,7 +428,7 @@ components:
425
428
  - null
426
429
  description: |
427
430
  What your licence permits you to do with the data. Null when there
428
- is no licence.
431
+ is no licence, which is every family with standing `unlicensed`.
429
432
  starts:
430
433
  type: string
431
434
  format: date-time
@@ -483,10 +486,7 @@ components:
483
486
  not a gap - the `_provider` catalogs are keyed by provider id, so no
484
487
  MMDB exists for them.
485
488
  items:
486
- type: string
487
- enum:
488
- - csvgz
489
- - mmdb
489
+ $ref: '#/components/schemas/DatabaseFormat'
490
490
  Download:
491
491
  type: object
492
492
  description: One download ATTEMPT, refusals included.
@@ -26,7 +26,7 @@ from .models import (
26
26
  Standing,
27
27
  )
28
28
 
29
- __version__ = "1.2.2"
29
+ __version__ = "2.1.0"
30
30
 
31
31
  __all__ = [
32
32
  "DEFAULT_BASE_URL",
@@ -1,13 +1,17 @@
1
- """Plumbing the sync and the async client both need: transport wiring, response
2
- unwrapping, and the retry policy."""
1
+ """Plumbing the sync and the async client both need: transport wiring, the deadline on
2
+ each attempt, response unwrapping, and the retry policy."""
3
3
 
4
4
  from __future__ import annotations
5
5
 
6
+ import asyncio
6
7
  import contextlib
8
+ import contextvars
7
9
  import json
8
10
  import os
11
+ import threading
9
12
  from collections.abc import Awaitable, Callable, Iterator
10
13
  from pathlib import Path
14
+ from types import ModuleType
11
15
  from typing import IO, Any, TypeVar, cast
12
16
 
13
17
  import httpx
@@ -19,7 +23,7 @@ from .models import Database, Download, to_database, to_download
19
23
 
20
24
  DEFAULT_BASE_URL = "https://internetdata.io"
21
25
  DEFAULT_RETRIES = 2
22
- DEFAULT_TIMEOUT = 10.0
26
+ DEFAULT_TIMEOUT = 30.0
23
27
  DEFAULT_DOWNLOADS_LIMIT = 50
24
28
 
25
29
  # One chunk of a transfer, and therefore the ceiling on what a download of any size
@@ -172,8 +176,10 @@ def send(call: Callable[[], Response[Any]]) -> Response[Any]:
172
176
  something this client cannot read, which is a failed request rather than a bug in the
173
177
  caller's code, so all three become the one error type here.
174
178
 
175
- The lambda does nothing but call the generated function, which is what keeps this
176
- catch from swallowing a fault of our own.
179
+ The call does nothing but build one generated request, send it and hand the answer to
180
+ the generated decoder, which is what keeps this catch from swallowing a fault of our own.
181
+ An argument is converted before it, so a format this client does not publish is the
182
+ caller's `ValueError` rather than the server's failure.
177
183
  """
178
184
  try:
179
185
  return call()
@@ -189,6 +195,91 @@ async def send_async(call: Callable[[], Awaitable[Response[Any]]]) -> Response[A
189
195
  raise malformed(exc) from exc
190
196
 
191
197
 
198
+ def request(
199
+ endpoint: ModuleType, client: AuthenticatedClient, bound: float | None, **params: Any
200
+ ) -> Response[Any]:
201
+ """`send` for one generated endpoint, one attempt of it finished within `bound` seconds,
202
+ or unbounded when that is None.
203
+
204
+ Assembled from the endpoint module's `_get_kwargs` and `_build_response` because its
205
+ `sync_detailed` sends through httpx alone, and httpx has no bound on the attempt.
206
+ """
207
+
208
+ def call() -> Response[Any]:
209
+ http = client.get_httpx_client()
210
+ req = http.build_request(**endpoint._get_kwargs(**params), timeout=httpx.Timeout(bound))
211
+ res = exchange(http, req, bound)
212
+ return cast(Response[Any], endpoint._build_response(client=client, response=res))
213
+
214
+ return send(call)
215
+
216
+
217
+ async def request_async(
218
+ endpoint: ModuleType, client: AuthenticatedClient, bound: float | None, **params: Any
219
+ ) -> Response[Any]:
220
+ """`request`, awaited."""
221
+
222
+ async def call() -> Response[Any]:
223
+ http = client.get_async_httpx_client()
224
+ req = http.build_request(**endpoint._get_kwargs(**params), timeout=httpx.Timeout(bound))
225
+ res = await exchange_async(http, req, bound)
226
+ return cast(Response[Any], endpoint._build_response(client=client, response=res))
227
+
228
+ return await send_async(call)
229
+
230
+
231
+ def exchange(http: httpx.Client, req: httpx.Request, bound: float | None) -> httpx.Response:
232
+ """One attempt at `req`, its whole body read, finished within `bound` seconds or failed
233
+ as a `network` error.
234
+
235
+ httpx bounds each PHASE of a request (connect, write, every read), not the attempt, so a
236
+ body trickling in a byte at a time outlasts any timeout it is given. The attempt runs on
237
+ a thread of its own and the caller waits at most `bound` for it; one abandoned stops at
238
+ its next chunk, or at the per-phase bound `req` also carries.
239
+ """
240
+ if bound is None:
241
+ return http.send(req)
242
+ finished = threading.Event()
243
+ abandoned = threading.Event()
244
+ outcome: list[httpx.Response | BaseException] = []
245
+ context = contextvars.copy_context()
246
+
247
+ def attempt() -> None:
248
+ try:
249
+ outcome.append(context.run(_read_whole, http, req, abandoned))
250
+ except BaseException as exc: # noqa: BLE001 - raised again on the caller's thread
251
+ outcome.append(exc)
252
+ finally:
253
+ finished.set()
254
+
255
+ threading.Thread(target=attempt, name="internetdata-attempt", daemon=True).start()
256
+ try:
257
+ if not finished.wait(bound):
258
+ raise _deadline_passed(bound)
259
+ finally:
260
+ abandoned.set()
261
+ if isinstance(outcome[0], BaseException):
262
+ raise outcome[0]
263
+ return outcome[0]
264
+
265
+
266
+ async def exchange_async(
267
+ http: httpx.AsyncClient, req: httpx.Request, bound: float | None
268
+ ) -> httpx.Response:
269
+ """`exchange`, awaited. Cancelling the attempt closes its connection, so no thread is
270
+ needed to leave it behind."""
271
+ if bound is None:
272
+ return await http.send(req)
273
+ deadline = asyncio.timeout(bound)
274
+ try:
275
+ async with deadline:
276
+ return await http.send(req)
277
+ except TimeoutError:
278
+ if not deadline.expired():
279
+ raise
280
+ raise _deadline_passed(bound) from None
281
+
282
+
192
283
  def malformed(exc: Exception) -> InternetDataError:
193
284
  return InternetDataError("server_error", f"malformed response from the API: {exc}")
194
285
 
@@ -273,6 +364,41 @@ def retry_delay(err: InternetDataError, attempt: int, retries: int) -> float | N
273
364
  return _BACKOFF_BASE * (2.0**attempt)
274
365
 
275
366
 
367
+ def _read_whole(
368
+ http: httpx.Client, req: httpx.Request, abandoned: threading.Event
369
+ ) -> httpx.Response:
370
+ res = http.send(req, stream=True)
371
+ try:
372
+ if isinstance(res.stream, httpx.SyncByteStream):
373
+ res.stream = _Abandonable(res.stream, abandoned, req)
374
+ res.read()
375
+ finally:
376
+ res.close()
377
+ return res
378
+
379
+
380
+ class _Abandonable(httpx.SyncByteStream):
381
+ def __init__(
382
+ self, inner: httpx.SyncByteStream, abandoned: threading.Event, req: httpx.Request
383
+ ) -> None:
384
+ self._inner = inner
385
+ self._abandoned = abandoned
386
+ self._req = req
387
+
388
+ def __iter__(self) -> Iterator[bytes]:
389
+ for chunk in self._inner:
390
+ if self._abandoned.is_set():
391
+ raise httpx.ReadError("abandoned once its deadline passed", request=self._req)
392
+ yield chunk
393
+
394
+ def close(self) -> None:
395
+ self._inner.close()
396
+
397
+
398
+ def _deadline_passed(bound: float) -> InternetDataError:
399
+ return InternetDataError("network", f"the request did not complete within {bound:g} seconds")
400
+
401
+
276
402
  # The generated Response declares a plain MutableMapping, but always carries httpx's
277
403
  # case-insensitive Headers. Rebuilding one keeps a header lookup case-blind whichever it
278
404
  # turns out to be, which matters for `Retry-After`.
@@ -5,8 +5,8 @@ import httpx
5
5
 
6
6
  from ... import errors
7
7
  from ...client import AuthenticatedClient, Client
8
- from ...models.database_checksum_v2_format import DatabaseChecksumV2Format
9
8
  from ...models.database_checksum_v2_response_200 import DatabaseChecksumV2Response200
9
+ from ...models.database_format import DatabaseFormat
10
10
  from ...models.error import Error
11
11
  from ...types import UNSET, Response
12
12
 
@@ -14,7 +14,7 @@ from ...types import UNSET, Response
14
14
  def _get_kwargs(
15
15
  *,
16
16
  id: str,
17
- format_: DatabaseChecksumV2Format,
17
+ format_: DatabaseFormat,
18
18
  ) -> dict[str, Any]:
19
19
 
20
20
  params: dict[str, Any] = {}
@@ -89,7 +89,7 @@ def sync_detailed(
89
89
  *,
90
90
  client: AuthenticatedClient,
91
91
  id: str,
92
- format_: DatabaseChecksumV2Format,
92
+ format_: DatabaseFormat,
93
93
  ) -> Response[DatabaseChecksumV2Response200 | Error]:
94
94
  """Checksums
95
95
 
@@ -97,7 +97,7 @@ def sync_detailed(
97
97
 
98
98
  Args:
99
99
  id (str): Example: vpn_ip_v1.
100
- format_ (DatabaseChecksumV2Format): Example: mmdb.
100
+ format_ (DatabaseFormat): A file format a database version is published in. Example: mmdb.
101
101
 
102
102
  Raises:
103
103
  errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
@@ -123,7 +123,7 @@ def sync(
123
123
  *,
124
124
  client: AuthenticatedClient,
125
125
  id: str,
126
- format_: DatabaseChecksumV2Format,
126
+ format_: DatabaseFormat,
127
127
  ) -> DatabaseChecksumV2Response200 | Error | None:
128
128
  """Checksums
129
129
 
@@ -131,7 +131,7 @@ def sync(
131
131
 
132
132
  Args:
133
133
  id (str): Example: vpn_ip_v1.
134
- format_ (DatabaseChecksumV2Format): Example: mmdb.
134
+ format_ (DatabaseFormat): A file format a database version is published in. Example: mmdb.
135
135
 
136
136
  Raises:
137
137
  errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
@@ -152,7 +152,7 @@ async def asyncio_detailed(
152
152
  *,
153
153
  client: AuthenticatedClient,
154
154
  id: str,
155
- format_: DatabaseChecksumV2Format,
155
+ format_: DatabaseFormat,
156
156
  ) -> Response[DatabaseChecksumV2Response200 | Error]:
157
157
  """Checksums
158
158
 
@@ -160,7 +160,7 @@ async def asyncio_detailed(
160
160
 
161
161
  Args:
162
162
  id (str): Example: vpn_ip_v1.
163
- format_ (DatabaseChecksumV2Format): Example: mmdb.
163
+ format_ (DatabaseFormat): A file format a database version is published in. Example: mmdb.
164
164
 
165
165
  Raises:
166
166
  errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
@@ -184,7 +184,7 @@ async def asyncio(
184
184
  *,
185
185
  client: AuthenticatedClient,
186
186
  id: str,
187
- format_: DatabaseChecksumV2Format,
187
+ format_: DatabaseFormat,
188
188
  ) -> DatabaseChecksumV2Response200 | Error | None:
189
189
  """Checksums
190
190
 
@@ -192,7 +192,7 @@ async def asyncio(
192
192
 
193
193
  Args:
194
194
  id (str): Example: vpn_ip_v1.
195
- format_ (DatabaseChecksumV2Format): Example: mmdb.
195
+ format_ (DatabaseFormat): A file format a database version is published in. Example: mmdb.
196
196
 
197
197
  Raises:
198
198
  errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
@@ -5,7 +5,7 @@ import httpx
5
5
 
6
6
  from ... import errors
7
7
  from ...client import AuthenticatedClient, Client
8
- from ...models.download_database_v2_format import DownloadDatabaseV2Format
8
+ from ...models.database_format import DatabaseFormat
9
9
  from ...models.error import Error
10
10
  from ...types import UNSET, Response
11
11
 
@@ -13,7 +13,7 @@ from ...types import UNSET, Response
13
13
  def _get_kwargs(
14
14
  *,
15
15
  id: str,
16
- format_: DownloadDatabaseV2Format,
16
+ format_: DatabaseFormat,
17
17
  ) -> dict[str, Any]:
18
18
 
19
19
  params: dict[str, Any] = {}
@@ -87,7 +87,7 @@ def sync_detailed(
87
87
  *,
88
88
  client: AuthenticatedClient,
89
89
  id: str,
90
- format_: DownloadDatabaseV2Format,
90
+ format_: DatabaseFormat,
91
91
  ) -> Response[Any | Error]:
92
92
  """Download
93
93
 
@@ -96,7 +96,7 @@ def sync_detailed(
96
96
 
97
97
  Args:
98
98
  id (str): Example: vpn_ip_v1.
99
- format_ (DownloadDatabaseV2Format): Example: mmdb.
99
+ format_ (DatabaseFormat): A file format a database version is published in. Example: mmdb.
100
100
 
101
101
  Raises:
102
102
  errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
@@ -122,7 +122,7 @@ def sync(
122
122
  *,
123
123
  client: AuthenticatedClient,
124
124
  id: str,
125
- format_: DownloadDatabaseV2Format,
125
+ format_: DatabaseFormat,
126
126
  ) -> Any | Error | None:
127
127
  """Download
128
128
 
@@ -131,7 +131,7 @@ def sync(
131
131
 
132
132
  Args:
133
133
  id (str): Example: vpn_ip_v1.
134
- format_ (DownloadDatabaseV2Format): Example: mmdb.
134
+ format_ (DatabaseFormat): A file format a database version is published in. Example: mmdb.
135
135
 
136
136
  Raises:
137
137
  errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
@@ -152,7 +152,7 @@ async def asyncio_detailed(
152
152
  *,
153
153
  client: AuthenticatedClient,
154
154
  id: str,
155
- format_: DownloadDatabaseV2Format,
155
+ format_: DatabaseFormat,
156
156
  ) -> Response[Any | Error]:
157
157
  """Download
158
158
 
@@ -161,7 +161,7 @@ async def asyncio_detailed(
161
161
 
162
162
  Args:
163
163
  id (str): Example: vpn_ip_v1.
164
- format_ (DownloadDatabaseV2Format): Example: mmdb.
164
+ format_ (DatabaseFormat): A file format a database version is published in. Example: mmdb.
165
165
 
166
166
  Raises:
167
167
  errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
@@ -185,7 +185,7 @@ async def asyncio(
185
185
  *,
186
186
  client: AuthenticatedClient,
187
187
  id: str,
188
- format_: DownloadDatabaseV2Format,
188
+ format_: DatabaseFormat,
189
189
  ) -> Any | Error | None:
190
190
  """Download
191
191
 
@@ -194,7 +194,7 @@ async def asyncio(
194
194
 
195
195
  Args:
196
196
  id (str): Example: vpn_ip_v1.
197
- format_ (DownloadDatabaseV2Format): Example: mmdb.
197
+ format_ (DatabaseFormat): A file format a database version is published in. Example: mmdb.
198
198
 
199
199
  Raises:
200
200
  errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
@@ -1,9 +1,8 @@
1
1
  """Contains all the data models used in inputs/outputs"""
2
2
 
3
3
  from .database import Database
4
- from .database_checksum_v2_format import DatabaseChecksumV2Format
5
4
  from .database_checksum_v2_response_200 import DatabaseChecksumV2Response200
6
- from .database_checksum_v2_response_200_format import DatabaseChecksumV2Response200Format
5
+ from .database_format import DatabaseFormat
7
6
  from .database_license_type_type_1 import DatabaseLicenseTypeType1
8
7
  from .database_license_type_type_2_type_1 import DatabaseLicenseTypeType2Type1
9
8
  from .database_license_type_type_3_type_1 import DatabaseLicenseTypeType3Type1
@@ -15,22 +14,19 @@ from .database_metadata_sample_additional_property_item import (
15
14
  )
16
15
  from .database_metadata_schema import DatabaseMetadataSchema
17
16
  from .database_metadata_size import DatabaseMetadataSize
18
- from .database_standing import DatabaseStanding
19
17
  from .database_version import DatabaseVersion
20
- from .database_version_formats_item import DatabaseVersionFormatsItem
21
18
  from .db_checksums import DbChecksums
22
19
  from .download import Download
23
- from .download_database_v2_format import DownloadDatabaseV2Format
24
20
  from .download_outcome import DownloadOutcome
25
21
  from .error import Error
26
22
  from .list_databases_response_200 import ListDatabasesResponse200
27
23
  from .list_downloads_response_200 import ListDownloadsResponse200
24
+ from .standing import Standing
28
25
 
29
26
  __all__ = (
30
27
  "Database",
31
- "DatabaseChecksumV2Format",
32
28
  "DatabaseChecksumV2Response200",
33
- "DatabaseChecksumV2Response200Format",
29
+ "DatabaseFormat",
34
30
  "DatabaseLicenseTypeType1",
35
31
  "DatabaseLicenseTypeType2Type1",
36
32
  "DatabaseLicenseTypeType3Type1",
@@ -40,14 +36,12 @@ __all__ = (
40
36
  "DatabaseMetadataSampleAdditionalPropertyItem",
41
37
  "DatabaseMetadataSchema",
42
38
  "DatabaseMetadataSize",
43
- "DatabaseStanding",
44
39
  "DatabaseVersion",
45
- "DatabaseVersionFormatsItem",
46
40
  "DbChecksums",
47
41
  "Download",
48
- "DownloadDatabaseV2Format",
49
42
  "DownloadOutcome",
50
43
  "Error",
51
44
  "ListDatabasesResponse200",
52
45
  "ListDownloadsResponse200",
46
+ "Standing",
53
47
  )
@@ -10,7 +10,7 @@ from attrs import field as _attrs_field
10
10
  from ..models.database_license_type_type_1 import DatabaseLicenseTypeType1
11
11
  from ..models.database_license_type_type_2_type_1 import DatabaseLicenseTypeType2Type1
12
12
  from ..models.database_license_type_type_3_type_1 import DatabaseLicenseTypeType3Type1
13
- from ..models.database_standing import DatabaseStanding
13
+ from ..models.standing import Standing
14
14
 
15
15
  if TYPE_CHECKING:
16
16
  from ..models.database_version import DatabaseVersion
@@ -29,11 +29,12 @@ class Database:
29
29
  base (str): The family, e.g. `vpn_ip`. What a licence is held against. Example: vpn_ip.
30
30
  name (str): Example: VPN IP.
31
31
  summary (str): One line on what the newest version contains.
32
- standing (DatabaseStanding): `licensed` is a live grant, `expired` one whose term has ended, and
33
- `unlicensed` a database published but never bought.
32
+ standing (Standing): Where your licence for a database family stands today. `licensed` is a
33
+ live grant, `expired` one whose term has ended, and `unlicensed` a
34
+ database published but never bought.
34
35
  license_type (DatabaseLicenseTypeType1 | DatabaseLicenseTypeType2Type1 | DatabaseLicenseTypeType3Type1 | None):
35
36
  What your licence permits you to do with the data. Null when there
36
- is no licence.
37
+ is no licence, which is every family with standing `unlicensed`.
37
38
  starts (datetime.datetime | None):
38
39
  expires (datetime.datetime | None): A hard stop. Null when the licence has no end date, which is the normal case
39
40
  for a rolling agreement, and when there is no licence. A rolling licence reports its turnover date in renews_at
@@ -49,7 +50,7 @@ class Database:
49
50
  base: str
50
51
  name: str
51
52
  summary: str
52
- standing: DatabaseStanding
53
+ standing: Standing
53
54
  license_type: (
54
55
  DatabaseLicenseTypeType1
55
56
  | DatabaseLicenseTypeType2Type1
@@ -141,7 +142,7 @@ class Database:
141
142
 
142
143
  summary = d.pop("summary")
143
144
 
144
- standing = DatabaseStanding(d.pop("standing"))
145
+ standing = Standing(d.pop("standing"))
145
146
 
146
147
  def _parse_license_type(
147
148
  data: object,
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Any, Self, TypeVar
6
6
  from attrs import define as _attrs_define
7
7
  from attrs import field as _attrs_field
8
8
 
9
- from ..models.database_checksum_v2_response_200_format import DatabaseChecksumV2Response200Format
9
+ from ..models.database_format import DatabaseFormat
10
10
 
11
11
  if TYPE_CHECKING:
12
12
  from ..models.db_checksums import DbChecksums
@@ -20,12 +20,12 @@ class DatabaseChecksumV2Response200:
20
20
  """
21
21
  Attributes:
22
22
  id (str):
23
- format_ (DatabaseChecksumV2Response200Format):
23
+ format_ (DatabaseFormat): A file format a database version is published in. Example: mmdb.
24
24
  checksums (DbChecksums):
25
25
  """
26
26
 
27
27
  id: str
28
- format_: DatabaseChecksumV2Response200Format
28
+ format_: DatabaseFormat
29
29
  checksums: DbChecksums
30
30
  additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
31
31
 
@@ -55,7 +55,7 @@ class DatabaseChecksumV2Response200:
55
55
  d = dict(src_dict)
56
56
  id = d.pop("id")
57
57
 
58
- format_ = DatabaseChecksumV2Response200Format(d.pop("format"))
58
+ format_ = DatabaseFormat(d.pop("format"))
59
59
 
60
60
  checksums = DbChecksums.from_dict(d.pop("checksums"))
61
61
 
@@ -1,7 +1,7 @@
1
1
  from enum import StrEnum
2
2
 
3
3
 
4
- class DownloadDatabaseV2Format(StrEnum):
4
+ class DatabaseFormat(StrEnum):
5
5
  CSVGZ = "csvgz"
6
6
  MMDB = "mmdb"
7
7
 
@@ -6,7 +6,7 @@ from typing import Any, Self, TypeVar
6
6
  from attrs import define as _attrs_define
7
7
  from attrs import field as _attrs_field
8
8
 
9
- from ..models.database_version_formats_item import DatabaseVersionFormatsItem
9
+ from ..models.database_format import DatabaseFormat
10
10
 
11
11
  T = TypeVar("T", bound="DatabaseVersion")
12
12
 
@@ -18,7 +18,7 @@ class DatabaseVersion:
18
18
  id (str): The versioned id. Pass this to `download`, `checksum` and `metadata`. Example: vpn_ip_v1.
19
19
  version (int): Example: 1.
20
20
  summary (str):
21
- formats (list[DatabaseVersionFormatsItem]): The formats this version is BUILT in. Asking for another is a 400,
21
+ formats (list[DatabaseFormat]): The formats this version is BUILT in. Asking for another is a 400,
22
22
  not a gap - the `_provider` catalogs are keyed by provider id, so no
23
23
  MMDB exists for them.
24
24
  """
@@ -26,7 +26,7 @@ class DatabaseVersion:
26
26
  id: str
27
27
  version: int
28
28
  summary: str
29
- formats: list[DatabaseVersionFormatsItem]
29
+ formats: list[DatabaseFormat]
30
30
  additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
31
31
 
32
32
  def to_dict(self) -> dict[str, Any]:
@@ -66,7 +66,7 @@ class DatabaseVersion:
66
66
  formats = []
67
67
  _formats = d.pop("formats")
68
68
  for formats_item_data in _formats:
69
- formats_item = DatabaseVersionFormatsItem(formats_item_data)
69
+ formats_item = DatabaseFormat(formats_item_data)
70
70
 
71
71
  formats.append(formats_item)
72
72
 
@@ -1,7 +1,7 @@
1
1
  from enum import StrEnum
2
2
 
3
3
 
4
- class DatabaseStanding(StrEnum):
4
+ class Standing(StrEnum):
5
5
  EXPIRED = "expired"
6
6
  LICENSED = "licensed"
7
7
  UNLICENSED = "unlicensed"