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
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Self, TypeVar
|
|
5
|
+
|
|
6
|
+
from attrs import define as _attrs_define
|
|
7
|
+
|
|
8
|
+
from ..types import UNSET, Unset
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from ..models.patient_address import PatientAddress
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
T = TypeVar("T", bound="PatientDemographics")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@_attrs_define
|
|
18
|
+
class PatientDemographics:
|
|
19
|
+
"""
|
|
20
|
+
Attributes:
|
|
21
|
+
first_name (str | Unset): Patient's legal first name.
|
|
22
|
+
last_name (str | Unset): Patient's legal last name.
|
|
23
|
+
birth_date (str | Unset): Patient's date of birth, ISO YYYY-MM-DD.
|
|
24
|
+
sex (str | Unset): Patient's sex.
|
|
25
|
+
phone (str | Unset): Patient's phone number.
|
|
26
|
+
email (str | Unset): Patient's email, used as the signer identity.
|
|
27
|
+
address (PatientAddress | Unset):
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
first_name: str | Unset = UNSET
|
|
31
|
+
last_name: str | Unset = UNSET
|
|
32
|
+
birth_date: str | Unset = UNSET
|
|
33
|
+
sex: str | Unset = UNSET
|
|
34
|
+
phone: str | Unset = UNSET
|
|
35
|
+
email: str | Unset = UNSET
|
|
36
|
+
address: PatientAddress | Unset = UNSET
|
|
37
|
+
|
|
38
|
+
def to_dict(self) -> dict[str, Any]:
|
|
39
|
+
first_name = self.first_name
|
|
40
|
+
|
|
41
|
+
last_name = self.last_name
|
|
42
|
+
|
|
43
|
+
birth_date = self.birth_date
|
|
44
|
+
|
|
45
|
+
sex = self.sex
|
|
46
|
+
|
|
47
|
+
phone = self.phone
|
|
48
|
+
|
|
49
|
+
email = self.email
|
|
50
|
+
|
|
51
|
+
address: dict[str, Any] | Unset = UNSET
|
|
52
|
+
if not isinstance(self.address, Unset):
|
|
53
|
+
address = self.address.to_dict()
|
|
54
|
+
|
|
55
|
+
field_dict: dict[str, Any] = {}
|
|
56
|
+
|
|
57
|
+
field_dict.update({})
|
|
58
|
+
if first_name is not UNSET:
|
|
59
|
+
field_dict["first_name"] = first_name
|
|
60
|
+
if last_name is not UNSET:
|
|
61
|
+
field_dict["last_name"] = last_name
|
|
62
|
+
if birth_date is not UNSET:
|
|
63
|
+
field_dict["birth_date"] = birth_date
|
|
64
|
+
if sex is not UNSET:
|
|
65
|
+
field_dict["sex"] = sex
|
|
66
|
+
if phone is not UNSET:
|
|
67
|
+
field_dict["phone"] = phone
|
|
68
|
+
if email is not UNSET:
|
|
69
|
+
field_dict["email"] = email
|
|
70
|
+
if address is not UNSET:
|
|
71
|
+
field_dict["address"] = address
|
|
72
|
+
|
|
73
|
+
return field_dict
|
|
74
|
+
|
|
75
|
+
@classmethod
|
|
76
|
+
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
|
|
77
|
+
from ..models.patient_address import PatientAddress
|
|
78
|
+
|
|
79
|
+
d = dict(src_dict)
|
|
80
|
+
first_name = d.pop("first_name", UNSET)
|
|
81
|
+
|
|
82
|
+
last_name = d.pop("last_name", UNSET)
|
|
83
|
+
|
|
84
|
+
birth_date = d.pop("birth_date", UNSET)
|
|
85
|
+
|
|
86
|
+
sex = d.pop("sex", UNSET)
|
|
87
|
+
|
|
88
|
+
phone = d.pop("phone", UNSET)
|
|
89
|
+
|
|
90
|
+
email = d.pop("email", UNSET)
|
|
91
|
+
|
|
92
|
+
_address = d.pop("address", UNSET)
|
|
93
|
+
address: PatientAddress | Unset
|
|
94
|
+
if isinstance(_address, Unset):
|
|
95
|
+
address = UNSET
|
|
96
|
+
else:
|
|
97
|
+
address = PatientAddress.from_dict(_address)
|
|
98
|
+
|
|
99
|
+
patient_demographics = cls(
|
|
100
|
+
first_name=first_name,
|
|
101
|
+
last_name=last_name,
|
|
102
|
+
birth_date=birth_date,
|
|
103
|
+
sex=sex,
|
|
104
|
+
phone=phone,
|
|
105
|
+
email=email,
|
|
106
|
+
address=address,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
return patient_demographics
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
from typing import Any, Self, TypeVar
|
|
5
|
+
|
|
6
|
+
from attrs import define as _attrs_define
|
|
7
|
+
|
|
8
|
+
from ..types import UNSET, Unset
|
|
9
|
+
|
|
10
|
+
T = TypeVar("T", bound="ProviderSeed")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@_attrs_define
|
|
14
|
+
class ProviderSeed:
|
|
15
|
+
"""
|
|
16
|
+
Attributes:
|
|
17
|
+
name (str): Provider name, as the patient would recognize it.
|
|
18
|
+
phone (str | Unset): Optional contact, for a provider that isn't reachable electronically.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
name: str
|
|
22
|
+
phone: str | Unset = UNSET
|
|
23
|
+
|
|
24
|
+
def to_dict(self) -> dict[str, Any]:
|
|
25
|
+
name = self.name
|
|
26
|
+
|
|
27
|
+
phone = self.phone
|
|
28
|
+
|
|
29
|
+
field_dict: dict[str, Any] = {}
|
|
30
|
+
|
|
31
|
+
field_dict.update(
|
|
32
|
+
{
|
|
33
|
+
"name": name,
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
if phone is not UNSET:
|
|
37
|
+
field_dict["phone"] = phone
|
|
38
|
+
|
|
39
|
+
return field_dict
|
|
40
|
+
|
|
41
|
+
@classmethod
|
|
42
|
+
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
|
|
43
|
+
d = dict(src_dict)
|
|
44
|
+
name = d.pop("name")
|
|
45
|
+
|
|
46
|
+
phone = d.pop("phone", UNSET)
|
|
47
|
+
|
|
48
|
+
provider_seed = cls(
|
|
49
|
+
name=name,
|
|
50
|
+
phone=phone,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
return provider_seed
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
from typing import Any, Self, TypeVar
|
|
5
|
+
|
|
6
|
+
from attrs import define as _attrs_define
|
|
7
|
+
|
|
8
|
+
from ..models.token_request_grant_type import TokenRequestGrantType
|
|
9
|
+
from ..types import UNSET, Unset
|
|
10
|
+
|
|
11
|
+
T = TypeVar("T", bound="TokenRequest")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@_attrs_define
|
|
15
|
+
class TokenRequest:
|
|
16
|
+
"""
|
|
17
|
+
Attributes:
|
|
18
|
+
grant_type (TokenRequestGrantType): The OAuth grant. authorization_code (redirect flow) is not yet available.
|
|
19
|
+
device_code (str | Unset): Required for the device_code grant.
|
|
20
|
+
refresh_token (str | Unset): Required for the refresh_token grant.
|
|
21
|
+
client_id (str | Unset): Client id, if not sent via HTTP Basic.
|
|
22
|
+
client_secret (str | Unset): Client secret, if not sent via HTTP Basic.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
grant_type: TokenRequestGrantType
|
|
26
|
+
device_code: str | Unset = UNSET
|
|
27
|
+
refresh_token: str | Unset = UNSET
|
|
28
|
+
client_id: str | Unset = UNSET
|
|
29
|
+
client_secret: str | Unset = UNSET
|
|
30
|
+
|
|
31
|
+
def to_dict(self) -> dict[str, Any]:
|
|
32
|
+
grant_type = self.grant_type.value
|
|
33
|
+
|
|
34
|
+
device_code = self.device_code
|
|
35
|
+
|
|
36
|
+
refresh_token = self.refresh_token
|
|
37
|
+
|
|
38
|
+
client_id = self.client_id
|
|
39
|
+
|
|
40
|
+
client_secret = self.client_secret
|
|
41
|
+
|
|
42
|
+
field_dict: dict[str, Any] = {}
|
|
43
|
+
|
|
44
|
+
field_dict.update(
|
|
45
|
+
{
|
|
46
|
+
"grant_type": grant_type,
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
if device_code is not UNSET:
|
|
50
|
+
field_dict["device_code"] = device_code
|
|
51
|
+
if refresh_token is not UNSET:
|
|
52
|
+
field_dict["refresh_token"] = refresh_token
|
|
53
|
+
if client_id is not UNSET:
|
|
54
|
+
field_dict["client_id"] = client_id
|
|
55
|
+
if client_secret is not UNSET:
|
|
56
|
+
field_dict["client_secret"] = client_secret
|
|
57
|
+
|
|
58
|
+
return field_dict
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
|
|
62
|
+
d = dict(src_dict)
|
|
63
|
+
grant_type = TokenRequestGrantType(d.pop("grant_type"))
|
|
64
|
+
|
|
65
|
+
device_code = d.pop("device_code", UNSET)
|
|
66
|
+
|
|
67
|
+
refresh_token = d.pop("refresh_token", UNSET)
|
|
68
|
+
|
|
69
|
+
client_id = d.pop("client_id", UNSET)
|
|
70
|
+
|
|
71
|
+
client_secret = d.pop("client_secret", UNSET)
|
|
72
|
+
|
|
73
|
+
token_request = cls(
|
|
74
|
+
grant_type=grant_type,
|
|
75
|
+
device_code=device_code,
|
|
76
|
+
refresh_token=refresh_token,
|
|
77
|
+
client_id=client_id,
|
|
78
|
+
client_secret=client_secret,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
return token_request
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TokenRequestGrantType(str, Enum):
|
|
5
|
+
AUTHORIZATION_CODE = "authorization_code"
|
|
6
|
+
REFRESH_TOKEN = "refresh_token"
|
|
7
|
+
URNIETFPARAMSOAUTHGRANT_TYPEDEVICE_CODE = (
|
|
8
|
+
"urn:ietf:params:oauth:grant-type:device_code"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
def __str__(self) -> str:
|
|
12
|
+
return str(self.value)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
from typing import (
|
|
5
|
+
Any,
|
|
6
|
+
Literal,
|
|
7
|
+
Self,
|
|
8
|
+
TypeVar,
|
|
9
|
+
cast,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from attrs import define as _attrs_define
|
|
13
|
+
|
|
14
|
+
T = TypeVar("T", bound="TokenResponse")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@_attrs_define
|
|
18
|
+
class TokenResponse:
|
|
19
|
+
"""
|
|
20
|
+
Attributes:
|
|
21
|
+
access_token (str): Consent-scoped access token for the /fhir data plane.
|
|
22
|
+
token_type (Literal['Bearer']):
|
|
23
|
+
expires_in (int): Seconds until the access token expires.
|
|
24
|
+
refresh_token (str): Rotating refresh token. The previous one is invalidated.
|
|
25
|
+
consent_id (str): The consent these tokens are scoped to.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
access_token: str
|
|
29
|
+
token_type: Literal["Bearer"]
|
|
30
|
+
expires_in: int
|
|
31
|
+
refresh_token: str
|
|
32
|
+
consent_id: str
|
|
33
|
+
|
|
34
|
+
def to_dict(self) -> dict[str, Any]:
|
|
35
|
+
access_token = self.access_token
|
|
36
|
+
|
|
37
|
+
token_type = self.token_type
|
|
38
|
+
|
|
39
|
+
expires_in = self.expires_in
|
|
40
|
+
|
|
41
|
+
refresh_token = self.refresh_token
|
|
42
|
+
|
|
43
|
+
consent_id = self.consent_id
|
|
44
|
+
|
|
45
|
+
field_dict: dict[str, Any] = {}
|
|
46
|
+
|
|
47
|
+
field_dict.update(
|
|
48
|
+
{
|
|
49
|
+
"access_token": access_token,
|
|
50
|
+
"token_type": token_type,
|
|
51
|
+
"expires_in": expires_in,
|
|
52
|
+
"refresh_token": refresh_token,
|
|
53
|
+
"consent_id": consent_id,
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
return field_dict
|
|
58
|
+
|
|
59
|
+
@classmethod
|
|
60
|
+
def from_dict(cls, src_dict: Mapping[str, Any]) -> Self:
|
|
61
|
+
d = dict(src_dict)
|
|
62
|
+
access_token = d.pop("access_token")
|
|
63
|
+
|
|
64
|
+
token_type = cast(Literal["Bearer"], d.pop("token_type"))
|
|
65
|
+
if token_type != "Bearer":
|
|
66
|
+
raise ValueError(
|
|
67
|
+
f"token_type must match const 'Bearer', got '{token_type}'"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
expires_in = d.pop("expires_in")
|
|
71
|
+
|
|
72
|
+
refresh_token = d.pop("refresh_token")
|
|
73
|
+
|
|
74
|
+
consent_id = d.pop("consent_id")
|
|
75
|
+
|
|
76
|
+
token_response = cls(
|
|
77
|
+
access_token=access_token,
|
|
78
|
+
token_type=token_type,
|
|
79
|
+
expires_in=expires_in,
|
|
80
|
+
refresh_token=refresh_token,
|
|
81
|
+
consent_id=consent_id,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
return token_response
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Contains some shared types for properties"""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping, MutableMapping
|
|
4
|
+
from http import HTTPStatus
|
|
5
|
+
from typing import IO, BinaryIO, Generic, Literal, TypeVar
|
|
6
|
+
|
|
7
|
+
from attrs import define
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Unset:
|
|
11
|
+
def __bool__(self) -> Literal[False]:
|
|
12
|
+
return False
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
UNSET: Unset = Unset()
|
|
16
|
+
|
|
17
|
+
# The types that `httpx.Client(files=)` can accept, copied from that library.
|
|
18
|
+
FileContent = IO[bytes] | bytes | str
|
|
19
|
+
FileTypes = (
|
|
20
|
+
# (filename, file (or bytes), content_type)
|
|
21
|
+
tuple[str | None, FileContent, str | None]
|
|
22
|
+
# (filename, file (or bytes), content_type, headers)
|
|
23
|
+
| tuple[str | None, FileContent, str | None, Mapping[str, str]]
|
|
24
|
+
)
|
|
25
|
+
RequestFiles = list[tuple[str, FileTypes]]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@define
|
|
29
|
+
class File:
|
|
30
|
+
"""Contains information for file uploads"""
|
|
31
|
+
|
|
32
|
+
payload: BinaryIO
|
|
33
|
+
file_name: str | None = None
|
|
34
|
+
mime_type: str | None = None
|
|
35
|
+
|
|
36
|
+
def to_tuple(self) -> FileTypes:
|
|
37
|
+
"""Return a tuple representation that httpx will accept for multipart/form-data"""
|
|
38
|
+
return self.file_name, self.payload, self.mime_type
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
T = TypeVar("T")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@define
|
|
45
|
+
class Response(Generic[T]):
|
|
46
|
+
"""A response from an endpoint"""
|
|
47
|
+
|
|
48
|
+
status_code: HTTPStatus
|
|
49
|
+
content: bytes
|
|
50
|
+
headers: MutableMapping[str, str]
|
|
51
|
+
parsed: T | None
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
__all__ = ["UNSET", "File", "FileTypes", "RequestFiles", "Response", "Unset"]
|