internetdata 2.7.4__tar.gz → 2.8.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.
- {internetdata-2.7.4 → internetdata-2.8.0}/PKG-INFO +1 -1
- {internetdata-2.7.4 → internetdata-2.8.0}/spec/openapi.yaml +132 -9
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/__init__.py +1 -1
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/authorization/oauth_authorize.py +20 -10
- internetdata-2.8.0/src/internetdata/_generated/api/authorization/oauth_register.py +246 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/__init__.py +4 -0
- internetdata-2.8.0/src/internetdata/_generated/models/client_registration.py +126 -0
- internetdata-2.8.0/src/internetdata/_generated/models/client_registration_request.py +104 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/oauth_metadata.py +10 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/token_response.py +2 -1
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/models.py +54 -28
- {internetdata-2.7.4 → internetdata-2.8.0}/tests/test_client.py +44 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/.gitignore +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/LICENSE +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/README.md +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/pyproject.toml +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/scripts/download-spec.sh +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/scripts/generate.sh +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/scripts/publish.sh +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/scripts/v2_subset.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_core.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/__init__.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/__init__.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/account/__init__.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/account/account_identity.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/api_keys/__init__.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/api_keys/account_create_apikey.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/api_keys/account_list_apikeys.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/api_keys/account_reveal_apikey.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/api_keys/account_revoke_apikey.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/api_keys/account_rotate_apikey.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/authorization/__init__.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/authorization/oauth_device_authorization.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/authorization/oauth_metadata.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/authorization/oauth_revoke.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/authorization/oauth_token.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/database_v_2/__init__.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/database_v_2/database_checksum_v2.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/database_v_2/database_metadata_v2.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/database_v_2/download_database_v2.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/database_v_2/list_databases.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/database_v_2/list_downloads.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/organization/__init__.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/organization/account_org.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/api/organization/account_org_members.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/client.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/errors.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/account_create_apikey_request.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/account_created_apikey.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/account_org.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/account_org_ref.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/account_org_wrap.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/account_rc.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/account_revealed_apikey.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/account_user.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/apikey_detail.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/apikey_list.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database_checksum_v2_response_200.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database_format.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database_license_type_type_1.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database_license_type_type_2_type_1.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database_license_type_type_3_type_1.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database_metadata.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database_metadata_column.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database_metadata_sample.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database_metadata_sample_additional_property_item.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database_metadata_sample_size.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database_metadata_schema.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database_metadata_size.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/database_version.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/db_checksums.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/device_authorization.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/device_authorization_request.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/download.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/download_outcome.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/error.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/identity.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/list_databases_response_200.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/list_downloads_response_200.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/oauth_authorize_code_challenge_method.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/oauth_authorize_response_type.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/oauth_error.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/oauth_revoke_response_200.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/revoke_request.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/standing.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/models/token_request.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/_generated/types.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/aio.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/client.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/errors.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/src/internetdata/py.typed +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/testdata/testdata.json +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/tests/conftest.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/tests/helpers.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/tests/test_conformance.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/tests/test_download.py +0 -0
- {internetdata-2.7.4 → internetdata-2.8.0}/tests/test_oauth.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: internetdata
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.8.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
|
|
@@ -12,7 +12,7 @@ info:
|
|
|
12
12
|
email: support@internetdata.io
|
|
13
13
|
url: https://internetdata.io
|
|
14
14
|
termsOfService: https://internetdata.io/terms
|
|
15
|
-
version: 2026.10.
|
|
15
|
+
version: 2026.10.16
|
|
16
16
|
servers:
|
|
17
17
|
- url: https://internetdata.io
|
|
18
18
|
tags:
|
|
@@ -653,6 +653,56 @@ paths:
|
|
|
653
653
|
application/json:
|
|
654
654
|
schema:
|
|
655
655
|
$ref: '#/components/schemas/OauthError'
|
|
656
|
+
/oauth/register:
|
|
657
|
+
post:
|
|
658
|
+
operationId: oauthRegister
|
|
659
|
+
tags:
|
|
660
|
+
- Authorization
|
|
661
|
+
summary: Register
|
|
662
|
+
description: |
|
|
663
|
+
RFC 7591 dynamic client registration, for a client that cannot use a
|
|
664
|
+
Client ID Metadata Document. Post your client's metadata as JSON, then
|
|
665
|
+
use the `client_id` in the answer at `/oauth/authorize` and
|
|
666
|
+
`/oauth/token`. Nothing is kept until a person approves your client, so
|
|
667
|
+
registering again costs nothing and leaves nothing to clean up.
|
|
668
|
+
|
|
669
|
+
Each redirect URI must be https on a public host name, or http on a
|
|
670
|
+
loopback address (`127.0.0.1`, `[::1]`, `localhost`), which then
|
|
671
|
+
matches on any port. A custom URI scheme is refused: use a loopback
|
|
672
|
+
redirect instead. So is a host on one of our own domains.
|
|
673
|
+
|
|
674
|
+
`client_name` is shown to the person as your client's own claim, with
|
|
675
|
+
where its redirect goes beside it. A name that renders blank, or mixes
|
|
676
|
+
Latin letters with Cyrillic or Greek ones, is shown as an unnamed
|
|
677
|
+
application.
|
|
678
|
+
|
|
679
|
+
The client is public whatever you ask for: `token_endpoint_auth_method`
|
|
680
|
+
comes back `none`, there is no client secret, and every authorization
|
|
681
|
+
proves itself with PKCE. It may be granted `apikeys.use` at most.
|
|
682
|
+
security: []
|
|
683
|
+
requestBody:
|
|
684
|
+
required: true
|
|
685
|
+
content:
|
|
686
|
+
application/json:
|
|
687
|
+
schema:
|
|
688
|
+
$ref: '#/components/schemas/ClientRegistrationRequest'
|
|
689
|
+
responses:
|
|
690
|
+
'201':
|
|
691
|
+
description: The client, as registered.
|
|
692
|
+
content:
|
|
693
|
+
application/json:
|
|
694
|
+
schema:
|
|
695
|
+
$ref: '#/components/schemas/ClientRegistration'
|
|
696
|
+
'400':
|
|
697
|
+
description: |
|
|
698
|
+
`invalid_redirect_uri` names the redirect URI refused and why, and
|
|
699
|
+
`invalid_client_metadata` anything else, such as a client that
|
|
700
|
+
does not use the authorization code flow. `slow_down` means this
|
|
701
|
+
address registered too many clients in the last minute.
|
|
702
|
+
content:
|
|
703
|
+
application/json:
|
|
704
|
+
schema:
|
|
705
|
+
$ref: '#/components/schemas/OauthError'
|
|
656
706
|
/oauth/authorize:
|
|
657
707
|
get:
|
|
658
708
|
operationId: oauthAuthorize
|
|
@@ -669,13 +719,18 @@ paths:
|
|
|
669
719
|
with `token_endpoint_auth_method` `none` and your `redirect_uris`. An
|
|
670
720
|
https redirect URI must be on the same origin as the `client_id`; a
|
|
671
721
|
loopback one (`http://127.0.0.1`, `http://[::1]`, `http://localhost`)
|
|
672
|
-
matches on any port. Such a client is granted `apikeys.use` at most.
|
|
722
|
+
matches on any port. Such a client is granted `apikeys.use` at most. A
|
|
723
|
+
client registered at `/oauth/register` uses the `client_id` it was
|
|
724
|
+
given and one of the `redirect_uris` it registered.
|
|
673
725
|
|
|
674
726
|
An unknown `client_id` or an unregistered `redirect_uri` is shown to the
|
|
675
|
-
|
|
676
|
-
have not verified belongs to you is how an open redirector works.
|
|
677
|
-
|
|
678
|
-
`
|
|
727
|
+
person and never redirected, because sending an error to an address we
|
|
728
|
+
have not verified belongs to you is how an open redirector works. Any
|
|
729
|
+
other error in the request is shown to the person too: anyone can make a
|
|
730
|
+
client, so its `redirect_uri` is verified only as its own (RFC 9700
|
|
731
|
+
section 4.11.2). Only the person's answer comes back to your
|
|
732
|
+
`redirect_uri`: a `code`, or `error` `access_denied`, each with your
|
|
733
|
+
`state` and `iss`.
|
|
679
734
|
security: []
|
|
680
735
|
parameters:
|
|
681
736
|
- name: client_id
|
|
@@ -731,9 +786,9 @@ paths:
|
|
|
731
786
|
given that server.
|
|
732
787
|
responses:
|
|
733
788
|
'302':
|
|
734
|
-
description: A redirect to the consent screen
|
|
789
|
+
description: A redirect to the consent screen.
|
|
735
790
|
'400':
|
|
736
|
-
description: Shown to the
|
|
791
|
+
description: Shown to the person. No error in the request is sent to your redirect_uri.
|
|
737
792
|
'429':
|
|
738
793
|
description: Shown to the user. Too many authorizations from one address.
|
|
739
794
|
/oauth/token:
|
|
@@ -1485,6 +1540,9 @@ components:
|
|
|
1485
1540
|
client_id_metadata_document_supported:
|
|
1486
1541
|
type: boolean
|
|
1487
1542
|
description: Any client may sign in with an https `client_id` serving its own metadata.
|
|
1543
|
+
registration_endpoint:
|
|
1544
|
+
type: string
|
|
1545
|
+
description: RFC 7591 dynamic client registration, for a client that cannot serve its own metadata.
|
|
1488
1546
|
token_endpoint_auth_methods_supported:
|
|
1489
1547
|
type: array
|
|
1490
1548
|
items:
|
|
@@ -1600,7 +1658,8 @@ components:
|
|
|
1600
1658
|
type: string
|
|
1601
1659
|
description: |
|
|
1602
1660
|
Not part of OAuth, and only for our own clients: a client that signed
|
|
1603
|
-
in with a Client ID Metadata Document
|
|
1661
|
+
in with a Client ID Metadata Document or registered itself never
|
|
1662
|
+
receives a key. The API
|
|
1604
1663
|
key itself, so a device ends up holding an ordinary key. Returned by
|
|
1605
1664
|
the device code and authorization code grants only, never by a
|
|
1606
1665
|
refresh, and only alongside
|
|
@@ -1611,6 +1670,70 @@ components:
|
|
|
1611
1670
|
- access_token
|
|
1612
1671
|
- token_type
|
|
1613
1672
|
- expires_in
|
|
1673
|
+
ClientRegistrationRequest:
|
|
1674
|
+
type: object
|
|
1675
|
+
properties:
|
|
1676
|
+
redirect_uris:
|
|
1677
|
+
type: array
|
|
1678
|
+
items:
|
|
1679
|
+
type: string
|
|
1680
|
+
description: One to ten, each matched exactly, apart from a loopback one's port.
|
|
1681
|
+
client_name:
|
|
1682
|
+
type: string
|
|
1683
|
+
description: >-
|
|
1684
|
+
Shown to the person as your client's own claim, marked unverified, beside where its
|
|
1685
|
+
redirect goes.
|
|
1686
|
+
grant_types:
|
|
1687
|
+
type: array
|
|
1688
|
+
items:
|
|
1689
|
+
type: string
|
|
1690
|
+
description: Must include `authorization_code` when given.
|
|
1691
|
+
response_types:
|
|
1692
|
+
type: array
|
|
1693
|
+
items:
|
|
1694
|
+
type: string
|
|
1695
|
+
description: Must include `code` when given.
|
|
1696
|
+
token_endpoint_auth_method:
|
|
1697
|
+
type: string
|
|
1698
|
+
description: Read as `none`, whatever is sent.
|
|
1699
|
+
required:
|
|
1700
|
+
- redirect_uris
|
|
1701
|
+
ClientRegistration:
|
|
1702
|
+
type: object
|
|
1703
|
+
properties:
|
|
1704
|
+
client_id:
|
|
1705
|
+
type: string
|
|
1706
|
+
client_id_issued_at:
|
|
1707
|
+
type: integer
|
|
1708
|
+
description: Unix seconds.
|
|
1709
|
+
client_name:
|
|
1710
|
+
type: string
|
|
1711
|
+
description: As the person will see it.
|
|
1712
|
+
redirect_uris:
|
|
1713
|
+
type: array
|
|
1714
|
+
items:
|
|
1715
|
+
type: string
|
|
1716
|
+
grant_types:
|
|
1717
|
+
type: array
|
|
1718
|
+
items:
|
|
1719
|
+
type: string
|
|
1720
|
+
description: '`authorization_code` and `refresh_token`.'
|
|
1721
|
+
response_types:
|
|
1722
|
+
type: array
|
|
1723
|
+
items:
|
|
1724
|
+
type: string
|
|
1725
|
+
token_endpoint_auth_method:
|
|
1726
|
+
type: string
|
|
1727
|
+
description: Always `none`.
|
|
1728
|
+
scope:
|
|
1729
|
+
type: string
|
|
1730
|
+
description: 'The most this client may be granted: `apikeys.use`.'
|
|
1731
|
+
required:
|
|
1732
|
+
- client_id
|
|
1733
|
+
- client_id_issued_at
|
|
1734
|
+
- client_name
|
|
1735
|
+
- redirect_uris
|
|
1736
|
+
- token_endpoint_auth_method
|
|
1614
1737
|
RevokeRequest:
|
|
1615
1738
|
type: object
|
|
1616
1739
|
properties:
|
|
@@ -105,13 +105,18 @@ def sync_detailed(
|
|
|
105
105
|
with `token_endpoint_auth_method` `none` and your `redirect_uris`. An
|
|
106
106
|
https redirect URI must be on the same origin as the `client_id`; a
|
|
107
107
|
loopback one (`http://127.0.0.1`, `http://[::1]`, `http://localhost`)
|
|
108
|
-
matches on any port. Such a client is granted `apikeys.use` at most.
|
|
108
|
+
matches on any port. Such a client is granted `apikeys.use` at most. A
|
|
109
|
+
client registered at `/oauth/register` uses the `client_id` it was
|
|
110
|
+
given and one of the `redirect_uris` it registered.
|
|
109
111
|
|
|
110
112
|
An unknown `client_id` or an unregistered `redirect_uri` is shown to the
|
|
111
|
-
|
|
112
|
-
have not verified belongs to you is how an open redirector works.
|
|
113
|
-
|
|
114
|
-
`
|
|
113
|
+
person and never redirected, because sending an error to an address we
|
|
114
|
+
have not verified belongs to you is how an open redirector works. Any
|
|
115
|
+
other error in the request is shown to the person too: anyone can make a
|
|
116
|
+
client, so its `redirect_uri` is verified only as its own (RFC 9700
|
|
117
|
+
section 4.11.2). Only the person's answer comes back to your
|
|
118
|
+
`redirect_uri`: a `code`, or `error` `access_denied`, each with your
|
|
119
|
+
`state` and `iss`.
|
|
115
120
|
|
|
116
121
|
Args:
|
|
117
122
|
client_id (str):
|
|
@@ -172,13 +177,18 @@ async def asyncio_detailed(
|
|
|
172
177
|
with `token_endpoint_auth_method` `none` and your `redirect_uris`. An
|
|
173
178
|
https redirect URI must be on the same origin as the `client_id`; a
|
|
174
179
|
loopback one (`http://127.0.0.1`, `http://[::1]`, `http://localhost`)
|
|
175
|
-
matches on any port. Such a client is granted `apikeys.use` at most.
|
|
180
|
+
matches on any port. Such a client is granted `apikeys.use` at most. A
|
|
181
|
+
client registered at `/oauth/register` uses the `client_id` it was
|
|
182
|
+
given and one of the `redirect_uris` it registered.
|
|
176
183
|
|
|
177
184
|
An unknown `client_id` or an unregistered `redirect_uri` is shown to the
|
|
178
|
-
|
|
179
|
-
have not verified belongs to you is how an open redirector works.
|
|
180
|
-
|
|
181
|
-
`
|
|
185
|
+
person and never redirected, because sending an error to an address we
|
|
186
|
+
have not verified belongs to you is how an open redirector works. Any
|
|
187
|
+
other error in the request is shown to the person too: anyone can make a
|
|
188
|
+
client, so its `redirect_uri` is verified only as its own (RFC 9700
|
|
189
|
+
section 4.11.2). Only the person's answer comes back to your
|
|
190
|
+
`redirect_uri`: a `code`, or `error` `access_denied`, each with your
|
|
191
|
+
`state` and `iss`.
|
|
182
192
|
|
|
183
193
|
Args:
|
|
184
194
|
client_id (str):
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
from http import HTTPStatus
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import httpx
|
|
5
|
+
|
|
6
|
+
from ... import errors
|
|
7
|
+
from ...client import AuthenticatedClient, Client
|
|
8
|
+
from ...models.client_registration import ClientRegistration
|
|
9
|
+
from ...models.client_registration_request import ClientRegistrationRequest
|
|
10
|
+
from ...models.oauth_error import OauthError
|
|
11
|
+
from ...types import Response
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _get_kwargs(
|
|
15
|
+
*,
|
|
16
|
+
body: ClientRegistrationRequest,
|
|
17
|
+
) -> dict[str, Any]:
|
|
18
|
+
headers: dict[str, Any] = {}
|
|
19
|
+
|
|
20
|
+
_kwargs: dict[str, Any] = {
|
|
21
|
+
"method": "post",
|
|
22
|
+
"url": "/oauth/register",
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
_kwargs["json"] = body.to_dict()
|
|
26
|
+
|
|
27
|
+
headers["Content-Type"] = "application/json"
|
|
28
|
+
|
|
29
|
+
_kwargs["headers"] = headers
|
|
30
|
+
return _kwargs
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _parse_response(
|
|
34
|
+
*, client: AuthenticatedClient | Client, response: httpx.Response
|
|
35
|
+
) -> ClientRegistration | OauthError | None:
|
|
36
|
+
if response.status_code == 201:
|
|
37
|
+
response_201 = ClientRegistration.from_dict(response.json())
|
|
38
|
+
|
|
39
|
+
return response_201
|
|
40
|
+
|
|
41
|
+
if response.status_code == 400:
|
|
42
|
+
response_400 = OauthError.from_dict(response.json())
|
|
43
|
+
|
|
44
|
+
return response_400
|
|
45
|
+
|
|
46
|
+
if client.raise_on_unexpected_status:
|
|
47
|
+
raise errors.UnexpectedStatus(response.status_code, response.content)
|
|
48
|
+
else:
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _build_response(
|
|
53
|
+
*, client: AuthenticatedClient | Client, response: httpx.Response
|
|
54
|
+
) -> Response[ClientRegistration | OauthError]:
|
|
55
|
+
return Response(
|
|
56
|
+
status_code=HTTPStatus(response.status_code),
|
|
57
|
+
content=response.content,
|
|
58
|
+
headers=response.headers,
|
|
59
|
+
parsed=_parse_response(client=client, response=response),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def sync_detailed(
|
|
64
|
+
*,
|
|
65
|
+
client: AuthenticatedClient | Client,
|
|
66
|
+
body: ClientRegistrationRequest,
|
|
67
|
+
) -> Response[ClientRegistration | OauthError]:
|
|
68
|
+
"""Register
|
|
69
|
+
|
|
70
|
+
RFC 7591 dynamic client registration, for a client that cannot use a
|
|
71
|
+
Client ID Metadata Document. Post your client's metadata as JSON, then
|
|
72
|
+
use the `client_id` in the answer at `/oauth/authorize` and
|
|
73
|
+
`/oauth/token`. Nothing is kept until a person approves your client, so
|
|
74
|
+
registering again costs nothing and leaves nothing to clean up.
|
|
75
|
+
|
|
76
|
+
Each redirect URI must be https on a public host name, or http on a
|
|
77
|
+
loopback address (`127.0.0.1`, `[::1]`, `localhost`), which then
|
|
78
|
+
matches on any port. A custom URI scheme is refused: use a loopback
|
|
79
|
+
redirect instead. So is a host on one of our own domains.
|
|
80
|
+
|
|
81
|
+
`client_name` is shown to the person as your client's own claim, with
|
|
82
|
+
where its redirect goes beside it. A name that renders blank, or mixes
|
|
83
|
+
Latin letters with Cyrillic or Greek ones, is shown as an unnamed
|
|
84
|
+
application.
|
|
85
|
+
|
|
86
|
+
The client is public whatever you ask for: `token_endpoint_auth_method`
|
|
87
|
+
comes back `none`, there is no client secret, and every authorization
|
|
88
|
+
proves itself with PKCE. It may be granted `apikeys.use` at most.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
body (ClientRegistrationRequest):
|
|
92
|
+
|
|
93
|
+
Raises:
|
|
94
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
95
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
Response[ClientRegistration | OauthError]
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
kwargs = _get_kwargs(
|
|
102
|
+
body=body,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
response = client.get_httpx_client().request(
|
|
106
|
+
**kwargs,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
return _build_response(client=client, response=response)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def sync(
|
|
113
|
+
*,
|
|
114
|
+
client: AuthenticatedClient | Client,
|
|
115
|
+
body: ClientRegistrationRequest,
|
|
116
|
+
) -> ClientRegistration | OauthError | None:
|
|
117
|
+
"""Register
|
|
118
|
+
|
|
119
|
+
RFC 7591 dynamic client registration, for a client that cannot use a
|
|
120
|
+
Client ID Metadata Document. Post your client's metadata as JSON, then
|
|
121
|
+
use the `client_id` in the answer at `/oauth/authorize` and
|
|
122
|
+
`/oauth/token`. Nothing is kept until a person approves your client, so
|
|
123
|
+
registering again costs nothing and leaves nothing to clean up.
|
|
124
|
+
|
|
125
|
+
Each redirect URI must be https on a public host name, or http on a
|
|
126
|
+
loopback address (`127.0.0.1`, `[::1]`, `localhost`), which then
|
|
127
|
+
matches on any port. A custom URI scheme is refused: use a loopback
|
|
128
|
+
redirect instead. So is a host on one of our own domains.
|
|
129
|
+
|
|
130
|
+
`client_name` is shown to the person as your client's own claim, with
|
|
131
|
+
where its redirect goes beside it. A name that renders blank, or mixes
|
|
132
|
+
Latin letters with Cyrillic or Greek ones, is shown as an unnamed
|
|
133
|
+
application.
|
|
134
|
+
|
|
135
|
+
The client is public whatever you ask for: `token_endpoint_auth_method`
|
|
136
|
+
comes back `none`, there is no client secret, and every authorization
|
|
137
|
+
proves itself with PKCE. It may be granted `apikeys.use` at most.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
body (ClientRegistrationRequest):
|
|
141
|
+
|
|
142
|
+
Raises:
|
|
143
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
144
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
ClientRegistration | OauthError
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
return sync_detailed(
|
|
151
|
+
client=client,
|
|
152
|
+
body=body,
|
|
153
|
+
).parsed
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
async def asyncio_detailed(
|
|
157
|
+
*,
|
|
158
|
+
client: AuthenticatedClient | Client,
|
|
159
|
+
body: ClientRegistrationRequest,
|
|
160
|
+
) -> Response[ClientRegistration | OauthError]:
|
|
161
|
+
"""Register
|
|
162
|
+
|
|
163
|
+
RFC 7591 dynamic client registration, for a client that cannot use a
|
|
164
|
+
Client ID Metadata Document. Post your client's metadata as JSON, then
|
|
165
|
+
use the `client_id` in the answer at `/oauth/authorize` and
|
|
166
|
+
`/oauth/token`. Nothing is kept until a person approves your client, so
|
|
167
|
+
registering again costs nothing and leaves nothing to clean up.
|
|
168
|
+
|
|
169
|
+
Each redirect URI must be https on a public host name, or http on a
|
|
170
|
+
loopback address (`127.0.0.1`, `[::1]`, `localhost`), which then
|
|
171
|
+
matches on any port. A custom URI scheme is refused: use a loopback
|
|
172
|
+
redirect instead. So is a host on one of our own domains.
|
|
173
|
+
|
|
174
|
+
`client_name` is shown to the person as your client's own claim, with
|
|
175
|
+
where its redirect goes beside it. A name that renders blank, or mixes
|
|
176
|
+
Latin letters with Cyrillic or Greek ones, is shown as an unnamed
|
|
177
|
+
application.
|
|
178
|
+
|
|
179
|
+
The client is public whatever you ask for: `token_endpoint_auth_method`
|
|
180
|
+
comes back `none`, there is no client secret, and every authorization
|
|
181
|
+
proves itself with PKCE. It may be granted `apikeys.use` at most.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
body (ClientRegistrationRequest):
|
|
185
|
+
|
|
186
|
+
Raises:
|
|
187
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
188
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
Response[ClientRegistration | OauthError]
|
|
192
|
+
"""
|
|
193
|
+
|
|
194
|
+
kwargs = _get_kwargs(
|
|
195
|
+
body=body,
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
response = await client.get_async_httpx_client().request(**kwargs)
|
|
199
|
+
|
|
200
|
+
return _build_response(client=client, response=response)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
async def asyncio(
|
|
204
|
+
*,
|
|
205
|
+
client: AuthenticatedClient | Client,
|
|
206
|
+
body: ClientRegistrationRequest,
|
|
207
|
+
) -> ClientRegistration | OauthError | None:
|
|
208
|
+
"""Register
|
|
209
|
+
|
|
210
|
+
RFC 7591 dynamic client registration, for a client that cannot use a
|
|
211
|
+
Client ID Metadata Document. Post your client's metadata as JSON, then
|
|
212
|
+
use the `client_id` in the answer at `/oauth/authorize` and
|
|
213
|
+
`/oauth/token`. Nothing is kept until a person approves your client, so
|
|
214
|
+
registering again costs nothing and leaves nothing to clean up.
|
|
215
|
+
|
|
216
|
+
Each redirect URI must be https on a public host name, or http on a
|
|
217
|
+
loopback address (`127.0.0.1`, `[::1]`, `localhost`), which then
|
|
218
|
+
matches on any port. A custom URI scheme is refused: use a loopback
|
|
219
|
+
redirect instead. So is a host on one of our own domains.
|
|
220
|
+
|
|
221
|
+
`client_name` is shown to the person as your client's own claim, with
|
|
222
|
+
where its redirect goes beside it. A name that renders blank, or mixes
|
|
223
|
+
Latin letters with Cyrillic or Greek ones, is shown as an unnamed
|
|
224
|
+
application.
|
|
225
|
+
|
|
226
|
+
The client is public whatever you ask for: `token_endpoint_auth_method`
|
|
227
|
+
comes back `none`, there is no client secret, and every authorization
|
|
228
|
+
proves itself with PKCE. It may be granted `apikeys.use` at most.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
body (ClientRegistrationRequest):
|
|
232
|
+
|
|
233
|
+
Raises:
|
|
234
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
235
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
ClientRegistration | OauthError
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
return (
|
|
242
|
+
await asyncio_detailed(
|
|
243
|
+
client=client,
|
|
244
|
+
body=body,
|
|
245
|
+
)
|
|
246
|
+
).parsed
|
|
@@ -10,6 +10,8 @@ from .account_revealed_apikey import AccountRevealedApikey
|
|
|
10
10
|
from .account_user import AccountUser
|
|
11
11
|
from .apikey_detail import ApikeyDetail
|
|
12
12
|
from .apikey_list import ApikeyList
|
|
13
|
+
from .client_registration import ClientRegistration
|
|
14
|
+
from .client_registration_request import ClientRegistrationRequest
|
|
13
15
|
from .database import Database
|
|
14
16
|
from .database_checksum_v2_response_200 import DatabaseChecksumV2Response200
|
|
15
17
|
from .database_format import DatabaseFormat
|
|
@@ -56,6 +58,8 @@ __all__ = (
|
|
|
56
58
|
"AccountUser",
|
|
57
59
|
"ApikeyDetail",
|
|
58
60
|
"ApikeyList",
|
|
61
|
+
"ClientRegistration",
|
|
62
|
+
"ClientRegistrationRequest",
|
|
59
63
|
"Database",
|
|
60
64
|
"DatabaseChecksumV2Response200",
|
|
61
65
|
"DatabaseFormat",
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
from typing import Any, Self, TypeVar, cast
|
|
5
|
+
|
|
6
|
+
from attrs import define as _attrs_define
|
|
7
|
+
from attrs import field as _attrs_field
|
|
8
|
+
|
|
9
|
+
from ..types import UNSET, Unset
|
|
10
|
+
|
|
11
|
+
T = TypeVar("T", bound="ClientRegistration")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@_attrs_define
|
|
15
|
+
class ClientRegistration:
|
|
16
|
+
"""
|
|
17
|
+
Attributes:
|
|
18
|
+
client_id (str):
|
|
19
|
+
client_id_issued_at (int): Unix seconds.
|
|
20
|
+
client_name (str): As the person will see it.
|
|
21
|
+
redirect_uris (list[str]):
|
|
22
|
+
token_endpoint_auth_method (str): Always `none`.
|
|
23
|
+
grant_types (list[str] | Unset): `authorization_code` and `refresh_token`.
|
|
24
|
+
response_types (list[str] | Unset):
|
|
25
|
+
scope (str | Unset): The most this client may be granted: `apikeys.use`.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
client_id: str
|
|
29
|
+
client_id_issued_at: int
|
|
30
|
+
client_name: str
|
|
31
|
+
redirect_uris: list[str]
|
|
32
|
+
token_endpoint_auth_method: str
|
|
33
|
+
grant_types: list[str] | Unset = UNSET
|
|
34
|
+
response_types: list[str] | Unset = UNSET
|
|
35
|
+
scope: str | Unset = UNSET
|
|
36
|
+
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
|
37
|
+
|
|
38
|
+
def to_dict(self) -> dict[str, Any]:
|
|
39
|
+
client_id = self.client_id
|
|
40
|
+
|
|
41
|
+
client_id_issued_at = self.client_id_issued_at
|
|
42
|
+
|
|
43
|
+
client_name = self.client_name
|
|
44
|
+
|
|
45
|
+
redirect_uris = self.redirect_uris
|
|
46
|
+
|
|
47
|
+
token_endpoint_auth_method = self.token_endpoint_auth_method
|
|
48
|
+
|
|
49
|
+
grant_types: list[str] | Unset = UNSET
|
|
50
|
+
if not isinstance(self.grant_types, Unset):
|
|
51
|
+
grant_types = self.grant_types
|
|
52
|
+
|
|
53
|
+
response_types: list[str] | Unset = UNSET
|
|
54
|
+
if not isinstance(self.response_types, Unset):
|
|
55
|
+
response_types = self.response_types
|
|
56
|
+
|
|
57
|
+
scope = self.scope
|
|
58
|
+
|
|
59
|
+
field_dict: dict[str, Any] = {}
|
|
60
|
+
field_dict.update(self.additional_properties)
|
|
61
|
+
field_dict.update(
|
|
62
|
+
{
|
|
63
|
+
"client_id": client_id,
|
|
64
|
+
"client_id_issued_at": client_id_issued_at,
|
|
65
|
+
"client_name": client_name,
|
|
66
|
+
"redirect_uris": redirect_uris,
|
|
67
|
+
"token_endpoint_auth_method": token_endpoint_auth_method,
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
if grant_types is not UNSET:
|
|
71
|
+
field_dict["grant_types"] = grant_types
|
|
72
|
+
if response_types is not UNSET:
|
|
73
|
+
field_dict["response_types"] = response_types
|
|
74
|
+
if scope is not UNSET:
|
|
75
|
+
field_dict["scope"] = scope
|
|
76
|
+
|
|
77
|
+
return field_dict
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
|
|
81
|
+
d = dict(src_dict)
|
|
82
|
+
client_id = d.pop("client_id")
|
|
83
|
+
|
|
84
|
+
client_id_issued_at = d.pop("client_id_issued_at")
|
|
85
|
+
|
|
86
|
+
client_name = d.pop("client_name")
|
|
87
|
+
|
|
88
|
+
redirect_uris = cast(list[str], d.pop("redirect_uris"))
|
|
89
|
+
|
|
90
|
+
token_endpoint_auth_method = d.pop("token_endpoint_auth_method")
|
|
91
|
+
|
|
92
|
+
grant_types = cast(list[str], d.pop("grant_types", UNSET))
|
|
93
|
+
|
|
94
|
+
response_types = cast(list[str], d.pop("response_types", UNSET))
|
|
95
|
+
|
|
96
|
+
scope = d.pop("scope", UNSET)
|
|
97
|
+
|
|
98
|
+
client_registration = cls(
|
|
99
|
+
client_id=client_id,
|
|
100
|
+
client_id_issued_at=client_id_issued_at,
|
|
101
|
+
client_name=client_name,
|
|
102
|
+
redirect_uris=redirect_uris,
|
|
103
|
+
token_endpoint_auth_method=token_endpoint_auth_method,
|
|
104
|
+
grant_types=grant_types,
|
|
105
|
+
response_types=response_types,
|
|
106
|
+
scope=scope,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
client_registration.additional_properties = d
|
|
110
|
+
return client_registration
|
|
111
|
+
|
|
112
|
+
@property
|
|
113
|
+
def additional_keys(self) -> list[str]:
|
|
114
|
+
return list(self.additional_properties.keys())
|
|
115
|
+
|
|
116
|
+
def __getitem__(self, key: str) -> Any:
|
|
117
|
+
return self.additional_properties[key]
|
|
118
|
+
|
|
119
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
|
120
|
+
self.additional_properties[key] = value
|
|
121
|
+
|
|
122
|
+
def __delitem__(self, key: str) -> None:
|
|
123
|
+
del self.additional_properties[key]
|
|
124
|
+
|
|
125
|
+
def __contains__(self, key: str) -> bool:
|
|
126
|
+
return key in self.additional_properties
|