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.
- hubble_sdk/__init__.py +43 -0
- hubble_sdk/_generated/__init__.py +8 -0
- hubble_sdk/_generated/api/__init__.py +1 -0
- hubble_sdk/_generated/api/default/__init__.py +1 -0
- hubble_sdk/_generated/api/default/attach_client_authorization.py +220 -0
- hubble_sdk/_generated/api/default/create_consent_link.py +197 -0
- hubble_sdk/_generated/api/default/exchange_token.py +186 -0
- hubble_sdk/_generated/api/default/export_patient_pdf.py +194 -0
- hubble_sdk/_generated/api/default/get_consent.py +166 -0
- hubble_sdk/_generated/api/default/list_consents.py +191 -0
- hubble_sdk/_generated/api/default/read_fhir.py +182 -0
- hubble_sdk/_generated/api/default/revoke_consent.py +167 -0
- hubble_sdk/_generated/client.py +282 -0
- hubble_sdk/_generated/errors.py +16 -0
- hubble_sdk/_generated/models/__init__.py +59 -0
- hubble_sdk/_generated/models/api_error.py +42 -0
- hubble_sdk/_generated/models/attach_client_authorization_body.py +112 -0
- hubble_sdk/_generated/models/attach_client_authorization_response_201.py +100 -0
- hubble_sdk/_generated/models/attach_client_authorization_response_201_status.py +8 -0
- hubble_sdk/_generated/models/consent.py +160 -0
- hubble_sdk/_generated/models/consent_error.py +50 -0
- hubble_sdk/_generated/models/consent_link_request.py +88 -0
- hubble_sdk/_generated/models/consent_list.py +56 -0
- hubble_sdk/_generated/models/consent_source.py +63 -0
- hubble_sdk/_generated/models/consent_source_status.py +10 -0
- hubble_sdk/_generated/models/consent_source_type.py +9 -0
- hubble_sdk/_generated/models/consent_status.py +12 -0
- hubble_sdk/_generated/models/device_authorization_request.py +142 -0
- hubble_sdk/_generated/models/device_authorization_response.py +90 -0
- hubble_sdk/_generated/models/fhir_resource.py +62 -0
- hubble_sdk/_generated/models/o_auth_error.py +54 -0
- hubble_sdk/_generated/models/o_auth_error_error.py +16 -0
- hubble_sdk/_generated/models/operation_outcome.py +75 -0
- hubble_sdk/_generated/models/operation_outcome_issue_item.py +61 -0
- hubble_sdk/_generated/models/patient_address.py +69 -0
- hubble_sdk/_generated/models/patient_demographics.py +109 -0
- hubble_sdk/_generated/models/provider_seed.py +53 -0
- hubble_sdk/_generated/models/token_request.py +81 -0
- hubble_sdk/_generated/models/token_request_grant_type.py +12 -0
- hubble_sdk/_generated/models/token_response.py +84 -0
- hubble_sdk/_generated/types.py +54 -0
- hubble_sdk/_hubble.py +379 -0
- hubble_sdk_python-0.0.2.dist-info/METADATA +89 -0
- hubble_sdk_python-0.0.2.dist-info/RECORD +46 -0
- hubble_sdk_python-0.0.2.dist-info/WHEEL +4 -0
- 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 @@
|
|
|
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
|