destiny_sdk 0.7.3__tar.gz → 0.7.4__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.
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/PKG-INFO +1 -1
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/pyproject.toml +1 -1
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/enhancements.py +46 -1
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/identifiers.py +5 -2
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/test_enhancements.py +51 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/.gitignore +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/LICENSE +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/README.md +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/__init__.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/auth.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/client.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/core.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/imports.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/labs/__init__.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/labs/references.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/parsers/__init__.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/parsers/eppi_parser.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/parsers/exceptions.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/py.typed +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/references.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/robots.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/search.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/src/destiny_sdk/visibility.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/__init__.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/conftest.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/labs/test_references.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/parsers/test_eppi_parser.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/test_auth.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/test_client.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/test_data/destiny_references.jsonl +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/test_data/eppi_import.jsonl +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/test_data/eppi_import_with_annotations.jsonl +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/test_data/eppi_import_with_raw.jsonl +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/test_data/eppi_report.json +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/test_identifiers.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/test_references.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/test_robots.py +0 -0
- {destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: destiny_sdk
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.4
|
|
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>, Tim Repke <tim.repke@pik-potsdam.de>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -8,6 +8,7 @@ from typing import Annotated, Any, Literal, Self
|
|
|
8
8
|
from pydantic import UUID4, BaseModel, Field, HttpUrl, model_validator
|
|
9
9
|
|
|
10
10
|
from destiny_sdk.core import _JsonlFileInputMixIn
|
|
11
|
+
from destiny_sdk.identifiers import Identifier
|
|
11
12
|
from destiny_sdk.visibility import Visibility
|
|
12
13
|
|
|
13
14
|
|
|
@@ -26,6 +27,8 @@ class EnhancementType(StrEnum):
|
|
|
26
27
|
"""A free-form enhancement for tagging with labels."""
|
|
27
28
|
LOCATION = auto()
|
|
28
29
|
"""Locations where the reference can be found."""
|
|
30
|
+
REFERENCE_ASSOCIATION = auto()
|
|
31
|
+
"""Associations to other references."""
|
|
29
32
|
RAW = auto()
|
|
30
33
|
"""A free form enhancement for arbitrary/unstructured data."""
|
|
31
34
|
FULL_TEXT = auto()
|
|
@@ -56,7 +59,11 @@ class Authorship(BaseModel):
|
|
|
56
59
|
for our purposes.
|
|
57
60
|
"""
|
|
58
61
|
|
|
59
|
-
display_name: str = Field(
|
|
62
|
+
display_name: str = Field(
|
|
63
|
+
description="The display name of the author. "
|
|
64
|
+
"Expected format FIRSTNAME <MIDDLENAME> LASTNAME. "
|
|
65
|
+
"Providing display_name in an unexpected format will affect search performance."
|
|
66
|
+
)
|
|
60
67
|
orcid: str | None = Field(default=None, description="The ORCid of the author.")
|
|
61
68
|
position: AuthorPosition = Field(
|
|
62
69
|
description="The position of the author within the list of authors."
|
|
@@ -320,6 +327,43 @@ class LocationEnhancement(BaseModel):
|
|
|
320
327
|
)
|
|
321
328
|
|
|
322
329
|
|
|
330
|
+
class ReferenceAssociationType(StrEnum):
|
|
331
|
+
"""
|
|
332
|
+
The type of association between references.
|
|
333
|
+
|
|
334
|
+
Direction is important: "this reference <association_type> associated reference".
|
|
335
|
+
"""
|
|
336
|
+
|
|
337
|
+
CITES = auto()
|
|
338
|
+
"""This reference cites the related reference."""
|
|
339
|
+
IS_CITED_BY = auto()
|
|
340
|
+
"""This reference is cited by the related reference."""
|
|
341
|
+
IS_SIMILAR_TO = auto()
|
|
342
|
+
"""This reference is similar to the related reference."""
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
class ReferenceAssociationEnhancement(BaseModel):
|
|
346
|
+
"""An enhancement for storing associations between references."""
|
|
347
|
+
|
|
348
|
+
enhancement_type: Literal[EnhancementType.REFERENCE_ASSOCIATION] = (
|
|
349
|
+
EnhancementType.REFERENCE_ASSOCIATION
|
|
350
|
+
)
|
|
351
|
+
associated_reference_ids: list[Identifier] = Field(
|
|
352
|
+
min_length=1,
|
|
353
|
+
description=(
|
|
354
|
+
"A list of Identifiers which are associated to this reference. "
|
|
355
|
+
"These can either be ExternalIdentifiers or resolved repository UUID4s."
|
|
356
|
+
),
|
|
357
|
+
)
|
|
358
|
+
association_type: ReferenceAssociationType = Field(
|
|
359
|
+
description=(
|
|
360
|
+
"The type of association between this reference and the associated ones. "
|
|
361
|
+
"Direction is important: "
|
|
362
|
+
'"this reference <association_type> associated reference".'
|
|
363
|
+
)
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
|
|
323
367
|
class RawEnhancement(BaseModel):
|
|
324
368
|
"""
|
|
325
369
|
An enhancement for storing raw/arbitrary/unstructured data.
|
|
@@ -377,6 +421,7 @@ EnhancementContent = Annotated[
|
|
|
377
421
|
| AbstractContentEnhancement
|
|
378
422
|
| AnnotationEnhancement
|
|
379
423
|
| LocationEnhancement
|
|
424
|
+
| ReferenceAssociationEnhancement
|
|
380
425
|
| RawEnhancement,
|
|
381
426
|
Field(discriminator="enhancement_type"),
|
|
382
427
|
]
|
|
@@ -165,6 +165,9 @@ ExternalIdentifier = Annotated[
|
|
|
165
165
|
Field(discriminator="identifier_type"),
|
|
166
166
|
]
|
|
167
167
|
|
|
168
|
+
#: Any identifier including external identifiers and repository UUID4s.
|
|
169
|
+
Identifier = Annotated[ExternalIdentifier | UUID4, Field()]
|
|
170
|
+
|
|
168
171
|
ExternalIdentifierAdapter: TypeAdapter[ExternalIdentifier] = TypeAdapter(
|
|
169
172
|
ExternalIdentifier
|
|
170
173
|
)
|
|
@@ -245,7 +248,7 @@ class IdentifierLookup(BaseModel):
|
|
|
245
248
|
)
|
|
246
249
|
|
|
247
250
|
@classmethod
|
|
248
|
-
def from_identifier(cls, identifier:
|
|
251
|
+
def from_identifier(cls, identifier: Identifier) -> Self:
|
|
249
252
|
"""Create an IdentifierLookup from an ExternalIdentifier or UUID4."""
|
|
250
253
|
if isinstance(identifier, uuid.UUID):
|
|
251
254
|
return cls(identifier=str(identifier), identifier_type=None)
|
|
@@ -255,7 +258,7 @@ class IdentifierLookup(BaseModel):
|
|
|
255
258
|
other_identifier_name=getattr(identifier, "other_identifier_name", None),
|
|
256
259
|
)
|
|
257
260
|
|
|
258
|
-
def to_identifier(self) ->
|
|
261
|
+
def to_identifier(self) -> Identifier:
|
|
259
262
|
"""Convert into an ExternalIdentifier or UUID4 if it has no identifier_type."""
|
|
260
263
|
if self.identifier_type is None:
|
|
261
264
|
return UUID4(self.identifier)
|
|
@@ -173,3 +173,54 @@ def test_empty_location_enhancement_errors():
|
|
|
173
173
|
enhancement_type=destiny_sdk.enhancements.EnhancementType.LOCATION,
|
|
174
174
|
locations=[],
|
|
175
175
|
)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def test_association_enhancement_valid():
|
|
179
|
+
# Create valid association content
|
|
180
|
+
association_content = destiny_sdk.enhancements.ReferenceAssociationEnhancement(
|
|
181
|
+
enhancement_type=destiny_sdk.enhancements.EnhancementType.REFERENCE_ASSOCIATION,
|
|
182
|
+
associated_reference_ids=[
|
|
183
|
+
uuid.uuid4(),
|
|
184
|
+
destiny_sdk.identifiers.OpenAlexIdentifier(
|
|
185
|
+
identifier="https://openalex.org/W1234567890",
|
|
186
|
+
identifier_type=destiny_sdk.identifiers.ExternalIdentifierType.OPEN_ALEX,
|
|
187
|
+
),
|
|
188
|
+
],
|
|
189
|
+
association_type=destiny_sdk.enhancements.ReferenceAssociationType.CITES,
|
|
190
|
+
)
|
|
191
|
+
enhancement = destiny_sdk.enhancements.Enhancement(
|
|
192
|
+
id=uuid.uuid4(),
|
|
193
|
+
source="test_source",
|
|
194
|
+
visibility="public",
|
|
195
|
+
robot_version="1.0",
|
|
196
|
+
enhancement_type=destiny_sdk.enhancements.EnhancementType.REFERENCE_ASSOCIATION,
|
|
197
|
+
content=association_content,
|
|
198
|
+
reference_id=uuid.uuid4(),
|
|
199
|
+
)
|
|
200
|
+
assert (
|
|
201
|
+
enhancement.content.association_type
|
|
202
|
+
== destiny_sdk.enhancements.ReferenceAssociationType.CITES
|
|
203
|
+
)
|
|
204
|
+
assert enhancement.content.associated_reference_ids[1].identifier == "W1234567890"
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def test_association_enhancement_empty_associated_reference_ids_errors():
|
|
208
|
+
# Test that an empty associated_reference_ids list raises a validation error
|
|
209
|
+
with pytest.raises(ValidationError):
|
|
210
|
+
destiny_sdk.enhancements.ReferenceAssociationEnhancement(
|
|
211
|
+
enhancement_type=destiny_sdk.enhancements.EnhancementType.REFERENCE_ASSOCIATION,
|
|
212
|
+
associated_reference_ids=[],
|
|
213
|
+
association_type=destiny_sdk.enhancements.ReferenceAssociationType.CITES,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def test_association_enhancement_invalid_identifier_type_errors():
|
|
218
|
+
# Test that an invalid identifier type raises a validation error
|
|
219
|
+
with pytest.raises(ValidationError):
|
|
220
|
+
destiny_sdk.enhancements.ReferenceAssociationEnhancement(
|
|
221
|
+
enhancement_type=destiny_sdk.enhancements.EnhancementType.REFERENCE_ASSOCIATION,
|
|
222
|
+
associated_reference_ids=[
|
|
223
|
+
"random-string",
|
|
224
|
+
],
|
|
225
|
+
association_type=destiny_sdk.enhancements.ReferenceAssociationType.CITES,
|
|
226
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{destiny_sdk-0.7.3 → destiny_sdk-0.7.4}/tests/unit/test_data/eppi_import_with_annotations.jsonl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|