destiny_sdk 0.5.0__py3-none-any.whl → 0.5.1__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.
- destiny_sdk/identifiers.py +87 -2
- {destiny_sdk-0.5.0.dist-info → destiny_sdk-0.5.1.dist-info}/METADATA +1 -1
- {destiny_sdk-0.5.0.dist-info → destiny_sdk-0.5.1.dist-info}/RECORD +5 -5
- {destiny_sdk-0.5.0.dist-info → destiny_sdk-0.5.1.dist-info}/WHEEL +0 -0
- {destiny_sdk-0.5.0.dist-info → destiny_sdk-0.5.1.dist-info}/licenses/LICENSE +0 -0
destiny_sdk/identifiers.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""Identifier classes for the Destiny SDK."""
|
|
2
2
|
|
|
3
|
+
import uuid
|
|
3
4
|
from enum import StrEnum, auto
|
|
4
|
-
from typing import Annotated, Literal
|
|
5
|
+
from typing import Annotated, Literal, Self
|
|
5
6
|
|
|
6
|
-
from pydantic import UUID4, BaseModel, Field, field_validator
|
|
7
|
+
from pydantic import UUID4, BaseModel, Field, TypeAdapter, field_validator
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class ExternalIdentifierType(StrEnum):
|
|
@@ -94,6 +95,10 @@ ExternalIdentifier = Annotated[
|
|
|
94
95
|
Field(discriminator="identifier_type"),
|
|
95
96
|
]
|
|
96
97
|
|
|
98
|
+
ExternalIdentifierAdapter: TypeAdapter[ExternalIdentifier] = TypeAdapter(
|
|
99
|
+
ExternalIdentifier
|
|
100
|
+
)
|
|
101
|
+
|
|
97
102
|
|
|
98
103
|
class LinkedExternalIdentifier(BaseModel):
|
|
99
104
|
"""An external identifier which identifies a reference."""
|
|
@@ -105,3 +110,83 @@ class LinkedExternalIdentifier(BaseModel):
|
|
|
105
110
|
reference_id: UUID4 = Field(
|
|
106
111
|
description="The ID of the reference this identifier identifies."
|
|
107
112
|
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class IdentifierLookup(BaseModel):
|
|
116
|
+
"""An external identifier lookup."""
|
|
117
|
+
|
|
118
|
+
identifier: str = Field(description="The identifier value.")
|
|
119
|
+
identifier_type: ExternalIdentifierType | None = Field(
|
|
120
|
+
description="The type of identifier used. If not provided, it is assumed to"
|
|
121
|
+
" be a DESTINY identifier.",
|
|
122
|
+
)
|
|
123
|
+
other_identifier_name: str | None = Field(
|
|
124
|
+
default=None,
|
|
125
|
+
description="The name of the undocumented identifier type.",
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
def serialize(self) -> str:
|
|
129
|
+
"""Serialize the identifier lookup to a string."""
|
|
130
|
+
if self.identifier_type is None:
|
|
131
|
+
return self.identifier
|
|
132
|
+
if self.identifier_type == ExternalIdentifierType.OTHER:
|
|
133
|
+
return f"other:{self.other_identifier_name}:{self.identifier}"
|
|
134
|
+
return f"{self.identifier_type.value.lower()}:{self.identifier}"
|
|
135
|
+
|
|
136
|
+
@classmethod
|
|
137
|
+
def parse(cls, identifier_lookup_string: str, delimiter: str = ":") -> Self:
|
|
138
|
+
"""Parse an identifier string into an IdentifierLookup."""
|
|
139
|
+
if delimiter not in identifier_lookup_string:
|
|
140
|
+
try:
|
|
141
|
+
UUID4(identifier_lookup_string)
|
|
142
|
+
except ValueError as exc:
|
|
143
|
+
msg = (
|
|
144
|
+
f"Invalid identifier lookup string: {identifier_lookup_string}. "
|
|
145
|
+
"Must be UUIDv4 if no identifier type is specified."
|
|
146
|
+
)
|
|
147
|
+
raise ValueError(msg) from exc
|
|
148
|
+
return cls(
|
|
149
|
+
identifier=identifier_lookup_string,
|
|
150
|
+
identifier_type=None,
|
|
151
|
+
)
|
|
152
|
+
identifier_type, identifier = identifier_lookup_string.split(delimiter, 1)
|
|
153
|
+
if identifier_type == ExternalIdentifierType.OTHER:
|
|
154
|
+
if delimiter not in identifier:
|
|
155
|
+
msg = (
|
|
156
|
+
f"Invalid identifier lookup string: {identifier_lookup_string}. "
|
|
157
|
+
"Other identifier type must include other identifier name."
|
|
158
|
+
)
|
|
159
|
+
raise ValueError(msg)
|
|
160
|
+
other_identifier_type, identifier = identifier.split(delimiter, 1)
|
|
161
|
+
return cls(
|
|
162
|
+
identifier=identifier,
|
|
163
|
+
identifier_type=ExternalIdentifierType.OTHER,
|
|
164
|
+
other_identifier_name=other_identifier_type,
|
|
165
|
+
)
|
|
166
|
+
if identifier_type not in ExternalIdentifierType:
|
|
167
|
+
msg = (
|
|
168
|
+
f"Invalid identifier lookup string: {identifier_lookup_string}. "
|
|
169
|
+
f"Unknown identifier type: {identifier_type}."
|
|
170
|
+
)
|
|
171
|
+
raise ValueError(msg)
|
|
172
|
+
return cls(
|
|
173
|
+
identifier=identifier,
|
|
174
|
+
identifier_type=ExternalIdentifierType(identifier_type),
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
@classmethod
|
|
178
|
+
def from_identifier(cls, identifier: ExternalIdentifier | UUID4) -> Self:
|
|
179
|
+
"""Create an IdentifierLookup from an ExternalIdentifier or UUID4."""
|
|
180
|
+
if isinstance(identifier, uuid.UUID):
|
|
181
|
+
return cls(identifier=str(identifier), identifier_type=None)
|
|
182
|
+
return cls(
|
|
183
|
+
identifier=str(identifier.identifier),
|
|
184
|
+
identifier_type=identifier.identifier_type,
|
|
185
|
+
other_identifier_name=getattr(identifier, "other_identifier_name", None),
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
def to_identifier(self) -> ExternalIdentifier | UUID4:
|
|
189
|
+
"""Convert into an ExternalIdentifier or UUID4 if it has no identifier_type."""
|
|
190
|
+
if self.identifier_type is None:
|
|
191
|
+
return UUID4(self.identifier)
|
|
192
|
+
return ExternalIdentifierAdapter.validate_python(self.model_dump())
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: destiny_sdk
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: A software development kit (sdk) to support interaction with the DESTINY repository
|
|
5
5
|
Author-email: Adam Hamilton <adam@futureevidence.org>, Andrew Harvey <andrew@futureevidence.org>, Daniel Breves <daniel@futureevidence.org>, Jack Walmisley <jack@futureevidence.org>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -3,7 +3,7 @@ destiny_sdk/auth.py,sha256=bY72ywZEcG_67YBd9PrwgWTXkCf58rhLvVEXrtXbWtA,6247
|
|
|
3
3
|
destiny_sdk/client.py,sha256=fTBtuq5emT8ieNtCuCY8Y6xAKZJDLq8sG1WOvmjLz-I,4971
|
|
4
4
|
destiny_sdk/core.py,sha256=_FwDaczKTSaUSV_qfcnLhkBbZagh4ayFpN0qUwJ03-o,1448
|
|
5
5
|
destiny_sdk/enhancements.py,sha256=SkIlIlWKBN7Z-aXpQiy22SXrU7zVnKxaRb4F5yaFsO8,11503
|
|
6
|
-
destiny_sdk/identifiers.py,sha256=
|
|
6
|
+
destiny_sdk/identifiers.py,sha256=1N2cszBmnQoUeKm54-7MUTO-zTDuvW8U9OjTeAmhWvo,7182
|
|
7
7
|
destiny_sdk/imports.py,sha256=b-rh-dt3NsyLGxqmVzIzKaHiXhbw-3wtAaBN-ZW-i1E,5940
|
|
8
8
|
destiny_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
destiny_sdk/references.py,sha256=Dx-WKcv9gNJkKU9n52AYoEey7siTHR5_wBVBKSHND6Q,2321
|
|
@@ -11,7 +11,7 @@ destiny_sdk/robots.py,sha256=I_ZvMxwST52e8ovhv0-gPbOB3P9tptbRG0LrkNNOqKo,13463
|
|
|
11
11
|
destiny_sdk/visibility.py,sha256=8D44Q868YdScAt6eAFgXXrhonozXnv_Qa5w5yEGMPX8,577
|
|
12
12
|
destiny_sdk/parsers/__init__.py,sha256=d5gS--bXla_0I7e_9wTBnGWMXt2U8b-_ndeprTPe1hk,149
|
|
13
13
|
destiny_sdk/parsers/eppi_parser.py,sha256=rEOtt_5Kp3oktFlzRTLZ2x4_7aQ9-ba3FYpkaEnpnvs,5521
|
|
14
|
-
destiny_sdk-0.5.
|
|
15
|
-
destiny_sdk-0.5.
|
|
16
|
-
destiny_sdk-0.5.
|
|
17
|
-
destiny_sdk-0.5.
|
|
14
|
+
destiny_sdk-0.5.1.dist-info/METADATA,sha256=eKznxYvVJhW-IVlA16LHzJ2QtpzfG3RyBKk9e-x_o8w,2440
|
|
15
|
+
destiny_sdk-0.5.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
+
destiny_sdk-0.5.1.dist-info/licenses/LICENSE,sha256=6QURU4gvvTjVZ5rfp5amZ6FtFvcpPhAGUjxF5WSZAHI,9138
|
|
17
|
+
destiny_sdk-0.5.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|