hubble-sdk-python 0.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. hubble_sdk/__init__.py +43 -0
  2. hubble_sdk/_generated/__init__.py +8 -0
  3. hubble_sdk/_generated/api/__init__.py +1 -0
  4. hubble_sdk/_generated/api/default/__init__.py +1 -0
  5. hubble_sdk/_generated/api/default/attach_client_authorization.py +220 -0
  6. hubble_sdk/_generated/api/default/create_consent_link.py +197 -0
  7. hubble_sdk/_generated/api/default/exchange_token.py +186 -0
  8. hubble_sdk/_generated/api/default/export_patient_pdf.py +194 -0
  9. hubble_sdk/_generated/api/default/get_consent.py +166 -0
  10. hubble_sdk/_generated/api/default/list_consents.py +191 -0
  11. hubble_sdk/_generated/api/default/read_fhir.py +182 -0
  12. hubble_sdk/_generated/api/default/revoke_consent.py +167 -0
  13. hubble_sdk/_generated/client.py +282 -0
  14. hubble_sdk/_generated/errors.py +16 -0
  15. hubble_sdk/_generated/models/__init__.py +59 -0
  16. hubble_sdk/_generated/models/api_error.py +42 -0
  17. hubble_sdk/_generated/models/attach_client_authorization_body.py +112 -0
  18. hubble_sdk/_generated/models/attach_client_authorization_response_201.py +100 -0
  19. hubble_sdk/_generated/models/attach_client_authorization_response_201_status.py +8 -0
  20. hubble_sdk/_generated/models/consent.py +160 -0
  21. hubble_sdk/_generated/models/consent_error.py +50 -0
  22. hubble_sdk/_generated/models/consent_link_request.py +88 -0
  23. hubble_sdk/_generated/models/consent_list.py +56 -0
  24. hubble_sdk/_generated/models/consent_source.py +63 -0
  25. hubble_sdk/_generated/models/consent_source_status.py +10 -0
  26. hubble_sdk/_generated/models/consent_source_type.py +9 -0
  27. hubble_sdk/_generated/models/consent_status.py +12 -0
  28. hubble_sdk/_generated/models/device_authorization_request.py +142 -0
  29. hubble_sdk/_generated/models/device_authorization_response.py +90 -0
  30. hubble_sdk/_generated/models/fhir_resource.py +62 -0
  31. hubble_sdk/_generated/models/o_auth_error.py +54 -0
  32. hubble_sdk/_generated/models/o_auth_error_error.py +16 -0
  33. hubble_sdk/_generated/models/operation_outcome.py +75 -0
  34. hubble_sdk/_generated/models/operation_outcome_issue_item.py +61 -0
  35. hubble_sdk/_generated/models/patient_address.py +69 -0
  36. hubble_sdk/_generated/models/patient_demographics.py +109 -0
  37. hubble_sdk/_generated/models/provider_seed.py +53 -0
  38. hubble_sdk/_generated/models/token_request.py +81 -0
  39. hubble_sdk/_generated/models/token_request_grant_type.py +12 -0
  40. hubble_sdk/_generated/models/token_response.py +84 -0
  41. hubble_sdk/_generated/types.py +54 -0
  42. hubble_sdk/_hubble.py +379 -0
  43. hubble_sdk_python-0.0.2.dist-info/METADATA +89 -0
  44. hubble_sdk_python-0.0.2.dist-info/RECORD +46 -0
  45. hubble_sdk_python-0.0.2.dist-info/WHEEL +4 -0
  46. hubble_sdk_python-0.0.2.dist-info/licenses/LICENSE +21 -0
hubble_sdk/__init__.py ADDED
@@ -0,0 +1,43 @@
1
+ """Python client for the Hubble Patient Access API.
2
+
3
+ Import the high-level client from here:
4
+
5
+ from hubble_sdk import Hubble
6
+
7
+ hub = Hubble(client_id="hbl_client_...", client_secret="hbl_prod_...")
8
+ link = hub.create_link(patient_ref="abc123")
9
+ print(link.verification_uri_complete) # send the patient here
10
+ session = hub.wait_for_authorization(link)
11
+ bundle = session.everything() # reads FHIR with the consent token
12
+
13
+ The generated low-level client lives under ``hubble_sdk._generated``
14
+ if you need direct access to raw operations and models.
15
+ """
16
+
17
+ from ._generated.models import (
18
+ Consent,
19
+ ConsentStatus,
20
+ DeviceAuthorizationResponse,
21
+ TokenResponse,
22
+ )
23
+ from ._hubble import (
24
+ ConsentTimeout,
25
+ Hubble,
26
+ HubbleError,
27
+ PatientSession,
28
+ PdfExport,
29
+ TokenSet,
30
+ )
31
+
32
+ __all__ = [
33
+ "Hubble",
34
+ "PatientSession",
35
+ "HubbleError",
36
+ "ConsentTimeout",
37
+ "TokenSet",
38
+ "PdfExport",
39
+ "Consent",
40
+ "ConsentStatus",
41
+ "DeviceAuthorizationResponse",
42
+ "TokenResponse",
43
+ ]
@@ -0,0 +1,8 @@
1
+ """A client library for accessing Hubble Patient Access API"""
2
+
3
+ from .client import AuthenticatedClient, Client
4
+
5
+ __all__ = (
6
+ "AuthenticatedClient",
7
+ "Client",
8
+ )
@@ -0,0 +1 @@
1
+ """Contains methods for accessing the API"""
@@ -0,0 +1 @@
1
+ """Contains endpoint functions for accessing the API"""
@@ -0,0 +1,220 @@
1
+ from http import HTTPStatus
2
+ from typing import Any
3
+ from urllib.parse import quote
4
+
5
+ import httpx
6
+
7
+ from ... import errors
8
+ from ...client import AuthenticatedClient, Client
9
+ from ...models.api_error import ApiError
10
+ from ...models.attach_client_authorization_body import AttachClientAuthorizationBody
11
+ from ...models.attach_client_authorization_response_201 import (
12
+ AttachClientAuthorizationResponse201,
13
+ )
14
+ from ...types import Response
15
+
16
+
17
+ def _get_kwargs(
18
+ id: str,
19
+ *,
20
+ body: AttachClientAuthorizationBody,
21
+ ) -> dict[str, Any]:
22
+ headers: dict[str, Any] = {}
23
+
24
+ _kwargs: dict[str, Any] = {
25
+ "method": "post",
26
+ "url": "/api/v1/consents/{id}/authorization".format(
27
+ id=quote(str(id), safe=""),
28
+ ),
29
+ }
30
+
31
+ _kwargs["files"] = body.to_multipart()
32
+
33
+ headers["Content-Type"] = "multipart/form-data; boundary=+++"
34
+
35
+ _kwargs["headers"] = headers
36
+ return _kwargs
37
+
38
+
39
+ def _parse_response(
40
+ *, client: AuthenticatedClient | Client, response: httpx.Response
41
+ ) -> ApiError | AttachClientAuthorizationResponse201 | None:
42
+ if response.status_code == 201:
43
+ response_201 = AttachClientAuthorizationResponse201.from_dict(response.json())
44
+
45
+ return response_201
46
+
47
+ if response.status_code == 400:
48
+ response_400 = ApiError.from_dict(response.json())
49
+
50
+ return response_400
51
+
52
+ if response.status_code == 401:
53
+ response_401 = ApiError.from_dict(response.json())
54
+
55
+ return response_401
56
+
57
+ if response.status_code == 403:
58
+ response_403 = ApiError.from_dict(response.json())
59
+
60
+ return response_403
61
+
62
+ if response.status_code == 404:
63
+ response_404 = ApiError.from_dict(response.json())
64
+
65
+ return response_404
66
+
67
+ if response.status_code == 413:
68
+ response_413 = ApiError.from_dict(response.json())
69
+
70
+ return response_413
71
+
72
+ if client.raise_on_unexpected_status:
73
+ raise errors.UnexpectedStatus(response.status_code, response.content)
74
+ else:
75
+ return None
76
+
77
+
78
+ def _build_response(
79
+ *, client: AuthenticatedClient | Client, response: httpx.Response
80
+ ) -> Response[ApiError | AttachClientAuthorizationResponse201]:
81
+ return Response(
82
+ status_code=HTTPStatus(response.status_code),
83
+ content=response.content,
84
+ headers=response.headers,
85
+ parsed=_parse_response(client=client, response=response),
86
+ )
87
+
88
+
89
+ def sync_detailed(
90
+ id: str,
91
+ *,
92
+ client: AuthenticatedClient,
93
+ body: AttachClientAuthorizationBody,
94
+ ) -> Response[ApiError | AttachClientAuthorizationResponse201]:
95
+ """Attach a customer-supplied HIPAA authorization
96
+
97
+ Upload an already-signed HIPAA authorization for a consent and grant delegated retrieval from the
98
+ providers it names. The artifact IS the evidence, so the consent is granted at once with no patient
99
+ step. Requires the `byo_hipaa_authorization` entitlement on your organization.
100
+
101
+ Args:
102
+ id (str):
103
+ body (AttachClientAuthorizationBody):
104
+
105
+ Raises:
106
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
107
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
108
+
109
+ Returns:
110
+ Response[ApiError | AttachClientAuthorizationResponse201]
111
+ """
112
+
113
+ kwargs = _get_kwargs(
114
+ id=id,
115
+ body=body,
116
+ )
117
+
118
+ response = client.get_httpx_client().request(
119
+ **kwargs,
120
+ )
121
+
122
+ return _build_response(client=client, response=response)
123
+
124
+
125
+ def sync(
126
+ id: str,
127
+ *,
128
+ client: AuthenticatedClient,
129
+ body: AttachClientAuthorizationBody,
130
+ ) -> ApiError | AttachClientAuthorizationResponse201 | None:
131
+ """Attach a customer-supplied HIPAA authorization
132
+
133
+ Upload an already-signed HIPAA authorization for a consent and grant delegated retrieval from the
134
+ providers it names. The artifact IS the evidence, so the consent is granted at once with no patient
135
+ step. Requires the `byo_hipaa_authorization` entitlement on your organization.
136
+
137
+ Args:
138
+ id (str):
139
+ body (AttachClientAuthorizationBody):
140
+
141
+ Raises:
142
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
143
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
144
+
145
+ Returns:
146
+ ApiError | AttachClientAuthorizationResponse201
147
+ """
148
+
149
+ return sync_detailed(
150
+ id=id,
151
+ client=client,
152
+ body=body,
153
+ ).parsed
154
+
155
+
156
+ async def asyncio_detailed(
157
+ id: str,
158
+ *,
159
+ client: AuthenticatedClient,
160
+ body: AttachClientAuthorizationBody,
161
+ ) -> Response[ApiError | AttachClientAuthorizationResponse201]:
162
+ """Attach a customer-supplied HIPAA authorization
163
+
164
+ Upload an already-signed HIPAA authorization for a consent and grant delegated retrieval from the
165
+ providers it names. The artifact IS the evidence, so the consent is granted at once with no patient
166
+ step. Requires the `byo_hipaa_authorization` entitlement on your organization.
167
+
168
+ Args:
169
+ id (str):
170
+ body (AttachClientAuthorizationBody):
171
+
172
+ Raises:
173
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
174
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
175
+
176
+ Returns:
177
+ Response[ApiError | AttachClientAuthorizationResponse201]
178
+ """
179
+
180
+ kwargs = _get_kwargs(
181
+ id=id,
182
+ body=body,
183
+ )
184
+
185
+ response = await client.get_async_httpx_client().request(**kwargs)
186
+
187
+ return _build_response(client=client, response=response)
188
+
189
+
190
+ async def asyncio(
191
+ id: str,
192
+ *,
193
+ client: AuthenticatedClient,
194
+ body: AttachClientAuthorizationBody,
195
+ ) -> ApiError | AttachClientAuthorizationResponse201 | None:
196
+ """Attach a customer-supplied HIPAA authorization
197
+
198
+ Upload an already-signed HIPAA authorization for a consent and grant delegated retrieval from the
199
+ providers it names. The artifact IS the evidence, so the consent is granted at once with no patient
200
+ step. Requires the `byo_hipaa_authorization` entitlement on your organization.
201
+
202
+ Args:
203
+ id (str):
204
+ body (AttachClientAuthorizationBody):
205
+
206
+ Raises:
207
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
208
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
209
+
210
+ Returns:
211
+ ApiError | AttachClientAuthorizationResponse201
212
+ """
213
+
214
+ return (
215
+ await asyncio_detailed(
216
+ id=id,
217
+ client=client,
218
+ body=body,
219
+ )
220
+ ).parsed
@@ -0,0 +1,197 @@
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.api_error import ApiError
9
+ from ...models.consent_link_request import ConsentLinkRequest
10
+ from ...models.device_authorization_request import DeviceAuthorizationRequest
11
+ from ...models.device_authorization_response import DeviceAuthorizationResponse
12
+ from ...types import UNSET, Response, Unset
13
+
14
+
15
+ def _get_kwargs(
16
+ *,
17
+ body: ConsentLinkRequest | DeviceAuthorizationRequest | Unset = UNSET,
18
+ ) -> dict[str, Any]:
19
+ headers: dict[str, Any] = {}
20
+
21
+ _kwargs: dict[str, Any] = {
22
+ "method": "post",
23
+ "url": "/api/v1/consents/oauth/device_authorization",
24
+ }
25
+
26
+ if isinstance(body, ConsentLinkRequest):
27
+ if not isinstance(body, Unset):
28
+ _kwargs["json"] = body.to_dict()
29
+
30
+ headers["Content-Type"] = "application/json"
31
+ if isinstance(body, DeviceAuthorizationRequest):
32
+ if not isinstance(body, Unset):
33
+ _kwargs["data"] = body.to_dict()
34
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
35
+
36
+ _kwargs["headers"] = headers
37
+ return _kwargs
38
+
39
+
40
+ def _parse_response(
41
+ *, client: AuthenticatedClient | Client, response: httpx.Response
42
+ ) -> ApiError | DeviceAuthorizationResponse | None:
43
+ if response.status_code == 200:
44
+ response_200 = DeviceAuthorizationResponse.from_dict(response.json())
45
+
46
+ return response_200
47
+
48
+ if response.status_code == 401:
49
+ response_401 = ApiError.from_dict(response.json())
50
+
51
+ return response_401
52
+
53
+ if client.raise_on_unexpected_status:
54
+ raise errors.UnexpectedStatus(response.status_code, response.content)
55
+ else:
56
+ return None
57
+
58
+
59
+ def _build_response(
60
+ *, client: AuthenticatedClient | Client, response: httpx.Response
61
+ ) -> Response[ApiError | DeviceAuthorizationResponse]:
62
+ return Response(
63
+ status_code=HTTPStatus(response.status_code),
64
+ content=response.content,
65
+ headers=response.headers,
66
+ parsed=_parse_response(client=client, response=response),
67
+ )
68
+
69
+
70
+ def sync_detailed(
71
+ *,
72
+ client: AuthenticatedClient,
73
+ body: ConsentLinkRequest | DeviceAuthorizationRequest | Unset = UNSET,
74
+ ) -> Response[ApiError | DeviceAuthorizationResponse]:
75
+ """Start the patient link flow
76
+
77
+ Mints a pending consent and a one-time patient link. Send the patient to
78
+ `verification_uri_complete`, then poll the token endpoint with `device_code` until they authorize.
79
+ Accepts a nested JSON body (recommended) or the flat RFC 8628 form encoding; both prefill the same
80
+ consent.
81
+
82
+ Args:
83
+ body (ConsentLinkRequest | Unset):
84
+ body (DeviceAuthorizationRequest | Unset):
85
+
86
+ Raises:
87
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
88
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
89
+
90
+ Returns:
91
+ Response[ApiError | DeviceAuthorizationResponse]
92
+ """
93
+
94
+ kwargs = _get_kwargs(
95
+ body=body,
96
+ )
97
+
98
+ response = client.get_httpx_client().request(
99
+ **kwargs,
100
+ )
101
+
102
+ return _build_response(client=client, response=response)
103
+
104
+
105
+ def sync(
106
+ *,
107
+ client: AuthenticatedClient,
108
+ body: ConsentLinkRequest | DeviceAuthorizationRequest | Unset = UNSET,
109
+ ) -> ApiError | DeviceAuthorizationResponse | None:
110
+ """Start the patient link flow
111
+
112
+ Mints a pending consent and a one-time patient link. Send the patient to
113
+ `verification_uri_complete`, then poll the token endpoint with `device_code` until they authorize.
114
+ Accepts a nested JSON body (recommended) or the flat RFC 8628 form encoding; both prefill the same
115
+ consent.
116
+
117
+ Args:
118
+ body (ConsentLinkRequest | Unset):
119
+ body (DeviceAuthorizationRequest | Unset):
120
+
121
+ Raises:
122
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
123
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
124
+
125
+ Returns:
126
+ ApiError | DeviceAuthorizationResponse
127
+ """
128
+
129
+ return sync_detailed(
130
+ client=client,
131
+ body=body,
132
+ ).parsed
133
+
134
+
135
+ async def asyncio_detailed(
136
+ *,
137
+ client: AuthenticatedClient,
138
+ body: ConsentLinkRequest | DeviceAuthorizationRequest | Unset = UNSET,
139
+ ) -> Response[ApiError | DeviceAuthorizationResponse]:
140
+ """Start the patient link flow
141
+
142
+ Mints a pending consent and a one-time patient link. Send the patient to
143
+ `verification_uri_complete`, then poll the token endpoint with `device_code` until they authorize.
144
+ Accepts a nested JSON body (recommended) or the flat RFC 8628 form encoding; both prefill the same
145
+ consent.
146
+
147
+ Args:
148
+ body (ConsentLinkRequest | Unset):
149
+ body (DeviceAuthorizationRequest | Unset):
150
+
151
+ Raises:
152
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
153
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
154
+
155
+ Returns:
156
+ Response[ApiError | DeviceAuthorizationResponse]
157
+ """
158
+
159
+ kwargs = _get_kwargs(
160
+ body=body,
161
+ )
162
+
163
+ response = await client.get_async_httpx_client().request(**kwargs)
164
+
165
+ return _build_response(client=client, response=response)
166
+
167
+
168
+ async def asyncio(
169
+ *,
170
+ client: AuthenticatedClient,
171
+ body: ConsentLinkRequest | DeviceAuthorizationRequest | Unset = UNSET,
172
+ ) -> ApiError | DeviceAuthorizationResponse | None:
173
+ """Start the patient link flow
174
+
175
+ Mints a pending consent and a one-time patient link. Send the patient to
176
+ `verification_uri_complete`, then poll the token endpoint with `device_code` until they authorize.
177
+ Accepts a nested JSON body (recommended) or the flat RFC 8628 form encoding; both prefill the same
178
+ consent.
179
+
180
+ Args:
181
+ body (ConsentLinkRequest | Unset):
182
+ body (DeviceAuthorizationRequest | Unset):
183
+
184
+ Raises:
185
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
186
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
187
+
188
+ Returns:
189
+ ApiError | DeviceAuthorizationResponse
190
+ """
191
+
192
+ return (
193
+ await asyncio_detailed(
194
+ client=client,
195
+ body=body,
196
+ )
197
+ ).parsed
@@ -0,0 +1,186 @@
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.o_auth_error import OAuthError
9
+ from ...models.token_request import TokenRequest
10
+ from ...models.token_response import TokenResponse
11
+ from ...types import Response
12
+
13
+
14
+ def _get_kwargs(
15
+ *,
16
+ body: TokenRequest,
17
+ ) -> dict[str, Any]:
18
+ headers: dict[str, Any] = {}
19
+
20
+ _kwargs: dict[str, Any] = {
21
+ "method": "post",
22
+ "url": "/api/v1/consents/oauth/token",
23
+ }
24
+
25
+ _kwargs["data"] = body.to_dict()
26
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
27
+
28
+ _kwargs["headers"] = headers
29
+ return _kwargs
30
+
31
+
32
+ def _parse_response(
33
+ *, client: AuthenticatedClient | Client, response: httpx.Response
34
+ ) -> OAuthError | TokenResponse | None:
35
+ if response.status_code == 200:
36
+ response_200 = TokenResponse.from_dict(response.json())
37
+
38
+ return response_200
39
+
40
+ if response.status_code == 400:
41
+ response_400 = OAuthError.from_dict(response.json())
42
+
43
+ return response_400
44
+
45
+ if response.status_code == 401:
46
+ response_401 = OAuthError.from_dict(response.json())
47
+
48
+ return response_401
49
+
50
+ if client.raise_on_unexpected_status:
51
+ raise errors.UnexpectedStatus(response.status_code, response.content)
52
+ else:
53
+ return None
54
+
55
+
56
+ def _build_response(
57
+ *, client: AuthenticatedClient | Client, response: httpx.Response
58
+ ) -> Response[OAuthError | TokenResponse]:
59
+ return Response(
60
+ status_code=HTTPStatus(response.status_code),
61
+ content=response.content,
62
+ headers=response.headers,
63
+ parsed=_parse_response(client=client, response=response),
64
+ )
65
+
66
+
67
+ def sync_detailed(
68
+ *,
69
+ client: AuthenticatedClient,
70
+ body: TokenRequest,
71
+ ) -> Response[OAuthError | TokenResponse]:
72
+ """Token endpoint
73
+
74
+ The single OAuth token endpoint. Dispatches on `grant_type`: the device_code grant redeems a link
75
+ into consent tokens; the refresh_token grant rotates them. Client auth via HTTP Basic or
76
+ `client_id`/`client_secret` form fields. Errors use the OAuth dialect.
77
+
78
+ Args:
79
+ body (TokenRequest):
80
+
81
+ Raises:
82
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
83
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
84
+
85
+ Returns:
86
+ Response[OAuthError | TokenResponse]
87
+ """
88
+
89
+ kwargs = _get_kwargs(
90
+ body=body,
91
+ )
92
+
93
+ response = client.get_httpx_client().request(
94
+ **kwargs,
95
+ )
96
+
97
+ return _build_response(client=client, response=response)
98
+
99
+
100
+ def sync(
101
+ *,
102
+ client: AuthenticatedClient,
103
+ body: TokenRequest,
104
+ ) -> OAuthError | TokenResponse | None:
105
+ """Token endpoint
106
+
107
+ The single OAuth token endpoint. Dispatches on `grant_type`: the device_code grant redeems a link
108
+ into consent tokens; the refresh_token grant rotates them. Client auth via HTTP Basic or
109
+ `client_id`/`client_secret` form fields. Errors use the OAuth dialect.
110
+
111
+ Args:
112
+ body (TokenRequest):
113
+
114
+ Raises:
115
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
116
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
117
+
118
+ Returns:
119
+ OAuthError | TokenResponse
120
+ """
121
+
122
+ return sync_detailed(
123
+ client=client,
124
+ body=body,
125
+ ).parsed
126
+
127
+
128
+ async def asyncio_detailed(
129
+ *,
130
+ client: AuthenticatedClient,
131
+ body: TokenRequest,
132
+ ) -> Response[OAuthError | TokenResponse]:
133
+ """Token endpoint
134
+
135
+ The single OAuth token endpoint. Dispatches on `grant_type`: the device_code grant redeems a link
136
+ into consent tokens; the refresh_token grant rotates them. Client auth via HTTP Basic or
137
+ `client_id`/`client_secret` form fields. Errors use the OAuth dialect.
138
+
139
+ Args:
140
+ body (TokenRequest):
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
+ Response[OAuthError | TokenResponse]
148
+ """
149
+
150
+ kwargs = _get_kwargs(
151
+ body=body,
152
+ )
153
+
154
+ response = await client.get_async_httpx_client().request(**kwargs)
155
+
156
+ return _build_response(client=client, response=response)
157
+
158
+
159
+ async def asyncio(
160
+ *,
161
+ client: AuthenticatedClient,
162
+ body: TokenRequest,
163
+ ) -> OAuthError | TokenResponse | None:
164
+ """Token endpoint
165
+
166
+ The single OAuth token endpoint. Dispatches on `grant_type`: the device_code grant redeems a link
167
+ into consent tokens; the refresh_token grant rotates them. Client auth via HTTP Basic or
168
+ `client_id`/`client_secret` form fields. Errors use the OAuth dialect.
169
+
170
+ Args:
171
+ body (TokenRequest):
172
+
173
+ Raises:
174
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
175
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
176
+
177
+ Returns:
178
+ OAuthError | TokenResponse
179
+ """
180
+
181
+ return (
182
+ await asyncio_detailed(
183
+ client=client,
184
+ body=body,
185
+ )
186
+ ).parsed