dyff-schema 0.13.0__py3-none-any.whl → 0.15.0__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.
Potentially problematic release.
This version of dyff-schema might be problematic. Click here for more details.
- dyff/schema/ids.py +19 -1
- dyff/schema/v0/r1/platform.py +163 -14
- {dyff_schema-0.13.0.dist-info → dyff_schema-0.15.0.dist-info}/METADATA +1 -1
- {dyff_schema-0.13.0.dist-info → dyff_schema-0.15.0.dist-info}/RECORD +8 -8
- {dyff_schema-0.13.0.dist-info → dyff_schema-0.15.0.dist-info}/WHEEL +1 -1
- {dyff_schema-0.13.0.dist-info → dyff_schema-0.15.0.dist-info}/LICENSE +0 -0
- {dyff_schema-0.13.0.dist-info → dyff_schema-0.15.0.dist-info}/NOTICE +0 -0
- {dyff_schema-0.13.0.dist-info → dyff_schema-0.15.0.dist-info}/top_level.txt +0 -0
dyff/schema/ids.py
CHANGED
|
@@ -24,6 +24,24 @@ def null_id() -> str:
|
|
|
24
24
|
return uuid.UUID(int=0).hex
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
def namespaced_id(namespace_id: str, entity_name: str) -> str:
|
|
28
|
+
"""Return an ID for a named entity whose name is unique within a namespace
|
|
29
|
+
corresponding to another entity ID.
|
|
30
|
+
|
|
31
|
+
This is used to model "child" resources that exist within the context of
|
|
32
|
+
a "parent".
|
|
33
|
+
|
|
34
|
+
:param namespace_id: The ID of the namespace.
|
|
35
|
+
:type namespace_id: str
|
|
36
|
+
:param entity_name: A name that is unique in the context of the namespace.
|
|
37
|
+
:type entity_name: str
|
|
38
|
+
:returns: The unique identifier of this (namespace, name)
|
|
39
|
+
combination -- a hex string representation of a UUID.
|
|
40
|
+
:rtype: str
|
|
41
|
+
"""
|
|
42
|
+
return uuid.uuid5(uuid.UUID(hex=namespace_id), entity_name).hex
|
|
43
|
+
|
|
44
|
+
|
|
27
45
|
def replication_id(evaluation_id: str, replication_index: int) -> str:
|
|
28
46
|
"""Return a unique identifier for a replication within an evaluation. Replications
|
|
29
47
|
in different evaluations will have different identifiers, so datasets from different
|
|
@@ -37,4 +55,4 @@ def replication_id(evaluation_id: str, replication_index: int) -> str:
|
|
|
37
55
|
combination -- a hex string representation of a UUID.
|
|
38
56
|
:rtype: str
|
|
39
57
|
"""
|
|
40
|
-
return
|
|
58
|
+
return namespaced_id(evaluation_id, str(replication_index))
|
dyff/schema/v0/r1/platform.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# SPDX-FileCopyrightText: 2024 UL Research Institutes
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
# fmt: off
|
|
3
4
|
"""Schema for the internal data representation of Dyff entities.
|
|
4
5
|
|
|
5
6
|
We use the following naming convention:
|
|
@@ -15,11 +16,14 @@ We use the following naming convention:
|
|
|
15
16
|
We include the full dependency data structure so that downstream
|
|
16
17
|
components don't need to be able to look it up by ID.
|
|
17
18
|
"""
|
|
19
|
+
|
|
20
|
+
# fmt: on
|
|
18
21
|
# mypy: disable-error-code="import-untyped"
|
|
19
22
|
import abc
|
|
20
23
|
import enum
|
|
21
24
|
import urllib.parse
|
|
22
25
|
from datetime import datetime
|
|
26
|
+
from decimal import Decimal
|
|
23
27
|
from enum import Enum
|
|
24
28
|
from typing import Any, Literal, NamedTuple, Optional, Type, Union
|
|
25
29
|
|
|
@@ -178,6 +182,7 @@ class Entities(str, enum.Enum):
|
|
|
178
182
|
Report = "Report"
|
|
179
183
|
Revision = "Revision"
|
|
180
184
|
SafetyCase = "SafetyCase"
|
|
185
|
+
Score = "Score"
|
|
181
186
|
|
|
182
187
|
|
|
183
188
|
class Resources(str, enum.Enum):
|
|
@@ -201,6 +206,7 @@ class Resources(str, enum.Enum):
|
|
|
201
206
|
Report = "reports"
|
|
202
207
|
Revision = "revisions"
|
|
203
208
|
SafetyCase = "safetycases"
|
|
209
|
+
Score = "scores"
|
|
204
210
|
|
|
205
211
|
Task = "tasks"
|
|
206
212
|
"""
|
|
@@ -1549,6 +1555,77 @@ class MethodScope(str, enum.Enum):
|
|
|
1549
1555
|
Evaluation = Entities.Evaluation.value
|
|
1550
1556
|
|
|
1551
1557
|
|
|
1558
|
+
class ScoreSpec(DyffSchemaBaseModel):
|
|
1559
|
+
name: str = pydantic.Field(
|
|
1560
|
+
description="The name of the score. Used as a key for retrieving score data."
|
|
1561
|
+
" Must be unique within the Method context.",
|
|
1562
|
+
)
|
|
1563
|
+
|
|
1564
|
+
title: str = pydantic.Field(
|
|
1565
|
+
description="The title text to use when displaying score information.",
|
|
1566
|
+
max_length=140,
|
|
1567
|
+
)
|
|
1568
|
+
|
|
1569
|
+
summary: str = pydantic.Field(
|
|
1570
|
+
description="A short text description of what the score measures.",
|
|
1571
|
+
max_length=140,
|
|
1572
|
+
)
|
|
1573
|
+
|
|
1574
|
+
valence: Literal["positive", "negative", "neutral"] = pydantic.Field(
|
|
1575
|
+
description="A score has 'positive' valence if 'more is better',"
|
|
1576
|
+
" 'negative' valence if 'less is better', and 'neutral' valence if"
|
|
1577
|
+
" 'better' is not meaningful for this score."
|
|
1578
|
+
)
|
|
1579
|
+
|
|
1580
|
+
priority: Literal["primary", "secondary"] = pydantic.Field(
|
|
1581
|
+
description="The 'primary' score will be displayed in any UI widgets"
|
|
1582
|
+
" that expect a single score."
|
|
1583
|
+
)
|
|
1584
|
+
|
|
1585
|
+
minimum: Optional[Decimal] = pydantic.Field(
|
|
1586
|
+
default=None, description="The minimum possible value, if known."
|
|
1587
|
+
)
|
|
1588
|
+
|
|
1589
|
+
maximum: Optional[Decimal] = pydantic.Field(
|
|
1590
|
+
default=None, description="The maximum possible value, if known."
|
|
1591
|
+
)
|
|
1592
|
+
|
|
1593
|
+
format: str = pydantic.Field(
|
|
1594
|
+
default="{quantity}",
|
|
1595
|
+
description="A Python 'format' string describing how to render the score"
|
|
1596
|
+
" as a string. You can use the keys 'quantity' and 'unit' in the format"
|
|
1597
|
+
" string (e.g., '{quantity} {unit}').",
|
|
1598
|
+
)
|
|
1599
|
+
|
|
1600
|
+
unit: Optional[str] = pydantic.Field(
|
|
1601
|
+
default=None,
|
|
1602
|
+
description="The unit of measure, if applicable (e.g., 'meters', 'kJ/g')."
|
|
1603
|
+
" Use standard SI abbreviations where possible for better indexing.",
|
|
1604
|
+
)
|
|
1605
|
+
|
|
1606
|
+
@pydantic.root_validator
|
|
1607
|
+
def _validate_minimum_maximum(cls, values):
|
|
1608
|
+
minimum = values.get("minimum")
|
|
1609
|
+
maximum = values.get("maximum")
|
|
1610
|
+
if minimum is not None and maximum is not None and minimum > maximum:
|
|
1611
|
+
raise ValueError(f"minimum {minimum} is greater than maximum {maximum}")
|
|
1612
|
+
return values
|
|
1613
|
+
|
|
1614
|
+
@pydantic.validator("format")
|
|
1615
|
+
def _validate_format(cls, v):
|
|
1616
|
+
try:
|
|
1617
|
+
cls._format_quantity(v, Decimal("3.14"), unit="kg")
|
|
1618
|
+
except Exception:
|
|
1619
|
+
raise ValueError(f"invalid format: '{v}'")
|
|
1620
|
+
return v
|
|
1621
|
+
|
|
1622
|
+
@classmethod
|
|
1623
|
+
def _format_quantity(
|
|
1624
|
+
cls, format: str, quantity: Decimal, *, unit: Optional[str] = None
|
|
1625
|
+
) -> str:
|
|
1626
|
+
return format.format(quantity=quantity, unit=unit)
|
|
1627
|
+
|
|
1628
|
+
|
|
1552
1629
|
class MethodBase(DyffSchemaBaseModel):
|
|
1553
1630
|
name: str = pydantic.Field(description="Descriptive name of the Method.")
|
|
1554
1631
|
|
|
@@ -1579,11 +1656,26 @@ class MethodBase(DyffSchemaBaseModel):
|
|
|
1579
1656
|
description="Specification of the Method output."
|
|
1580
1657
|
)
|
|
1581
1658
|
|
|
1659
|
+
scores: list[ScoreSpec] = pydantic.Field(
|
|
1660
|
+
default_factory=list,
|
|
1661
|
+
description="Specifications of the Scores that this Method produces.",
|
|
1662
|
+
)
|
|
1663
|
+
|
|
1582
1664
|
modules: list[str] = pydantic.Field(
|
|
1583
1665
|
default_factory=list,
|
|
1584
1666
|
description="Modules to load into the analysis environment",
|
|
1585
1667
|
)
|
|
1586
1668
|
|
|
1669
|
+
@pydantic.validator("scores")
|
|
1670
|
+
def _scores_validator(cls, scores: list[ScoreSpec]):
|
|
1671
|
+
if len(scores) > 0:
|
|
1672
|
+
primary_count = sum(score.priority == "primary" for score in scores)
|
|
1673
|
+
if primary_count != 1:
|
|
1674
|
+
raise ValueError(
|
|
1675
|
+
"scores: Must have exactly one score with .priority == 'primary'"
|
|
1676
|
+
)
|
|
1677
|
+
return scores
|
|
1678
|
+
|
|
1587
1679
|
|
|
1588
1680
|
class Method(DyffEntity, MethodBase):
|
|
1589
1681
|
kind: Literal["Method"] = Entities.Method.value
|
|
@@ -1659,11 +1751,32 @@ class AnalysisBase(DyffSchemaBaseModel):
|
|
|
1659
1751
|
)
|
|
1660
1752
|
|
|
1661
1753
|
|
|
1754
|
+
class AnalysisData(DyffSchemaBaseModel):
|
|
1755
|
+
"""Arbitrary additional data for the Analysis, specified as a key-value pair where
|
|
1756
|
+
the value is the data encoded in base64."""
|
|
1757
|
+
|
|
1758
|
+
key: str = pydantic.Field(
|
|
1759
|
+
description="Key identifying the data. For data about a Dyff entity,"
|
|
1760
|
+
" this should be the entity's ID."
|
|
1761
|
+
)
|
|
1762
|
+
|
|
1763
|
+
value: str = pydantic.Field(
|
|
1764
|
+
# Canonical base64 encoding
|
|
1765
|
+
# https://stackoverflow.com/a/64467300/3709935
|
|
1766
|
+
regex=r"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/][AQgw]==|[A-Za-z0-9+/]{2}[AEIMQUYcgkosw048]=)?$",
|
|
1767
|
+
description="Arbitrary data encoded in base64.",
|
|
1768
|
+
)
|
|
1769
|
+
|
|
1770
|
+
|
|
1662
1771
|
class Analysis(AnalysisBase):
|
|
1663
1772
|
method: ForeignMethod = pydantic.Field(
|
|
1664
1773
|
description="The analysis Method to run.",
|
|
1665
1774
|
)
|
|
1666
1775
|
|
|
1776
|
+
data: list[AnalysisData] = pydantic.Field(
|
|
1777
|
+
default_factory=list, description="Additional data to supply to the analysis."
|
|
1778
|
+
)
|
|
1779
|
+
|
|
1667
1780
|
|
|
1668
1781
|
class Measurement(DyffEntity, MeasurementSpec, Analysis):
|
|
1669
1782
|
kind: Literal["Measurement"] = Entities.Measurement.value
|
|
@@ -1685,25 +1798,55 @@ class SafetyCase(DyffEntity, SafetyCaseSpec, Analysis):
|
|
|
1685
1798
|
return None
|
|
1686
1799
|
|
|
1687
1800
|
|
|
1688
|
-
|
|
1689
|
-
|
|
1801
|
+
class ScoreMetadataRefs(AnalysisScope):
|
|
1802
|
+
"""References to other Dyff entities related to a Score."""
|
|
1803
|
+
|
|
1804
|
+
method: str = pydantic.Field(description="The Method that generates the score.")
|
|
1805
|
+
|
|
1806
|
+
|
|
1807
|
+
class ScoreMetadata(AnalysisScope):
|
|
1808
|
+
"""Metadata about a Score entity."""
|
|
1809
|
+
|
|
1810
|
+
refs: ScoreMetadataRefs = pydantic.Field(
|
|
1811
|
+
description="References to other related Dyff entities."
|
|
1812
|
+
)
|
|
1813
|
+
|
|
1814
|
+
|
|
1815
|
+
class ScoreData(ScoreSpec):
|
|
1816
|
+
"""ScoreData is an "instance" of a ScoreSpec containing the concrete measured value
|
|
1817
|
+
for the score."""
|
|
1818
|
+
|
|
1819
|
+
analysis: str = pydantic.Field(
|
|
1820
|
+
description="The Analysis that generated the current score instance."
|
|
1821
|
+
)
|
|
1690
1822
|
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1823
|
+
quantity: Decimal = pydantic.Field(
|
|
1824
|
+
description="The numeric quantity associated with the score."
|
|
1825
|
+
" Callers should set the desired precision explicitly."
|
|
1826
|
+
)
|
|
1694
1827
|
|
|
1695
|
-
|
|
1696
|
-
|
|
1828
|
+
text: str = pydantic.Field(
|
|
1829
|
+
description="A short text description of what the quantity means.",
|
|
1830
|
+
max_length=140,
|
|
1831
|
+
)
|
|
1697
1832
|
|
|
1698
|
-
|
|
1699
|
-
|
|
1833
|
+
def format_quantity(self) -> str:
|
|
1834
|
+
return self._format_quantity(self.format, self.quantity, unit=self.unit)
|
|
1700
1835
|
|
|
1701
1836
|
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1837
|
+
class Score(ScoreSpec):
|
|
1838
|
+
"""A Score is a numeric quantity describing an aspect of system performance.
|
|
1839
|
+
|
|
1840
|
+
Conceptually, a Score is an "instance" of a ScoreSpec.
|
|
1841
|
+
"""
|
|
1842
|
+
|
|
1843
|
+
kind: Literal["Score"] = Entities.Score.value
|
|
1844
|
+
|
|
1845
|
+
id: str = pydantic.Field(description="Unique identifier of the entity")
|
|
1846
|
+
|
|
1847
|
+
metadata: ScoreMetadata = pydantic.Field(
|
|
1848
|
+
description="Metadata about the score; used for indexing.",
|
|
1849
|
+
)
|
|
1707
1850
|
|
|
1708
1851
|
|
|
1709
1852
|
# ---------------------------------------------------------------------------
|
|
@@ -2024,6 +2167,7 @@ __all__ = [
|
|
|
2024
2167
|
"Analysis",
|
|
2025
2168
|
"AnalysisArgument",
|
|
2026
2169
|
"AnalysisBase",
|
|
2170
|
+
"AnalysisData",
|
|
2027
2171
|
"AnalysisInput",
|
|
2028
2172
|
"AnalysisOutputQueryFields",
|
|
2029
2173
|
"AnalysisScope",
|
|
@@ -2126,6 +2270,11 @@ __all__ = [
|
|
|
2126
2270
|
"SafetyCase",
|
|
2127
2271
|
"SafetyCaseSpec",
|
|
2128
2272
|
"SchemaAdapter",
|
|
2273
|
+
"Score",
|
|
2274
|
+
"ScoreData",
|
|
2275
|
+
"ScoreSpec",
|
|
2276
|
+
"ScoreMetadata",
|
|
2277
|
+
"ScoreMetadataRefs",
|
|
2129
2278
|
"Status",
|
|
2130
2279
|
"StorageSignedURL",
|
|
2131
2280
|
"TagName",
|
|
@@ -4,7 +4,7 @@ dyff/schema/annotations.py,sha256=nE6Jk1PLqlShj8uqjE_EzZC9zYnTDW5AVtQcjysiK8M,10
|
|
|
4
4
|
dyff/schema/base.py,sha256=jvaNtsSZyFfsdUZTcY_U-yfLY5_GyrMxSXhON2R9XR0,119
|
|
5
5
|
dyff/schema/copydoc.py,sha256=B4ZRpQmbFxi-3l9LCHvaJiVKb9VxADgC5vey804Febc,1075
|
|
6
6
|
dyff/schema/errors.py,sha256=ow3yiucU4wGkeLmapUURp3eyaebwGUwDaVTXpPcrA7M,1542
|
|
7
|
-
dyff/schema/ids.py,sha256=
|
|
7
|
+
dyff/schema/ids.py,sha256=M3kdGRYGPCMnFkRRo0nzHlntdJtBrRwGJ_9R7LlN0bI,2085
|
|
8
8
|
dyff/schema/platform.py,sha256=peHzGGSd5dQ-EFXrWDjBqMUtoOL3iCHxcV3XzW6Rjag,123
|
|
9
9
|
dyff/schema/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
dyff/schema/quantity.py,sha256=hhS9ybqW_6I--acPhkoZbFWASxFTEs7CUjO4pmpBJ98,3788
|
|
@@ -23,7 +23,7 @@ dyff/schema/v0/__init__.py,sha256=L5y8UhRnojerPYHumsxQJRcHCNz8Hj9NM8b47mewMNs,92
|
|
|
23
23
|
dyff/schema/v0/r1/__init__.py,sha256=L5y8UhRnojerPYHumsxQJRcHCNz8Hj9NM8b47mewMNs,92
|
|
24
24
|
dyff/schema/v0/r1/adapters.py,sha256=2t2oxsnGfSEDKKDIEYw4qqLXMH7qlFIwPVuLyUmbsHs,23552
|
|
25
25
|
dyff/schema/v0/r1/base.py,sha256=i7eOKXDGS8_J9k2aVObUTpSOnA8CAgRW7Quj1fSbyRg,19403
|
|
26
|
-
dyff/schema/v0/r1/platform.py,sha256=
|
|
26
|
+
dyff/schema/v0/r1/platform.py,sha256=Vg-JplBIQSBIgPWNwuFj_HFwJS8o7TSNyC-SvZc3BoU,72503
|
|
27
27
|
dyff/schema/v0/r1/requests.py,sha256=MMMtSfT9JpE2X7PLQGIuI4v7mMlJ-8DiZ65jc2hE0zc,10976
|
|
28
28
|
dyff/schema/v0/r1/test.py,sha256=X6dUyVd5svcPCI-PBMOAqEfK9jv3bRDvkQTJzwS96c0,10720
|
|
29
29
|
dyff/schema/v0/r1/version.py,sha256=isKAGuGxsdru8vDaYmI4YiZdJOu_wNxXK7u6QzD6FE4,392
|
|
@@ -35,9 +35,9 @@ dyff/schema/v0/r1/dataset/text.py,sha256=nLIn91Zlt0tNdXUklSgjJ-kEDxoPX32ISLkiv2D
|
|
|
35
35
|
dyff/schema/v0/r1/dataset/vision.py,sha256=aIe0fbfM_g3DsrDTdg2K803YKLjZBpurM_VJcJFuZLc,369
|
|
36
36
|
dyff/schema/v0/r1/io/__init__.py,sha256=L5y8UhRnojerPYHumsxQJRcHCNz8Hj9NM8b47mewMNs,92
|
|
37
37
|
dyff/schema/v0/r1/io/vllm.py,sha256=CUE9y8KthtUI7sD49S875rDmPvKotSXVIRaBS79aBZs,5320
|
|
38
|
-
dyff_schema-0.
|
|
39
|
-
dyff_schema-0.
|
|
40
|
-
dyff_schema-0.
|
|
41
|
-
dyff_schema-0.
|
|
42
|
-
dyff_schema-0.
|
|
43
|
-
dyff_schema-0.
|
|
38
|
+
dyff_schema-0.15.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
39
|
+
dyff_schema-0.15.0.dist-info/METADATA,sha256=QS7nIjfIS4L0D8v0Q6FBB9gyeP_0aIh-F1W1Dxy0_F0,3482
|
|
40
|
+
dyff_schema-0.15.0.dist-info/NOTICE,sha256=YONACu0s_Ui6jNi-wtEsVQbTU1JIkh8wvLH6d1-Ni_w,43
|
|
41
|
+
dyff_schema-0.15.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
|
42
|
+
dyff_schema-0.15.0.dist-info/top_level.txt,sha256=9e3VVdeX73t_sUJOPQPCcGtYO1JhoErhHIi3WoWGcFI,5
|
|
43
|
+
dyff_schema-0.15.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|