dyff-schema 0.14.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 +141 -14
- {dyff_schema-0.14.0.dist-info → dyff_schema-0.15.0.dist-info}/METADATA +1 -1
- {dyff_schema-0.14.0.dist-info → dyff_schema-0.15.0.dist-info}/RECORD +8 -8
- {dyff_schema-0.14.0.dist-info → dyff_schema-0.15.0.dist-info}/WHEEL +1 -1
- {dyff_schema-0.14.0.dist-info → dyff_schema-0.15.0.dist-info}/LICENSE +0 -0
- {dyff_schema-0.14.0.dist-info → dyff_schema-0.15.0.dist-info}/NOTICE +0 -0
- {dyff_schema-0.14.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
|
|
@@ -1706,25 +1798,55 @@ class SafetyCase(DyffEntity, SafetyCaseSpec, Analysis):
|
|
|
1706
1798
|
return None
|
|
1707
1799
|
|
|
1708
1800
|
|
|
1709
|
-
|
|
1710
|
-
|
|
1801
|
+
class ScoreMetadataRefs(AnalysisScope):
|
|
1802
|
+
"""References to other Dyff entities related to a Score."""
|
|
1711
1803
|
|
|
1712
|
-
|
|
1713
|
-
# description="The analysis Method to run.",
|
|
1714
|
-
# )
|
|
1804
|
+
method: str = pydantic.Field(description="The Method that generates the score.")
|
|
1715
1805
|
|
|
1716
|
-
# def dependencies(self) -> list[str]:
|
|
1717
|
-
# return [self.method.id] + [x.entity for x in self.inputs]
|
|
1718
1806
|
|
|
1719
|
-
|
|
1720
|
-
|
|
1807
|
+
class ScoreMetadata(AnalysisScope):
|
|
1808
|
+
"""Metadata about a Score entity."""
|
|
1721
1809
|
|
|
1810
|
+
refs: ScoreMetadataRefs = pydantic.Field(
|
|
1811
|
+
description="References to other related Dyff entities."
|
|
1812
|
+
)
|
|
1722
1813
|
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
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
|
+
)
|
|
1822
|
+
|
|
1823
|
+
quantity: Decimal = pydantic.Field(
|
|
1824
|
+
description="The numeric quantity associated with the score."
|
|
1825
|
+
" Callers should set the desired precision explicitly."
|
|
1826
|
+
)
|
|
1827
|
+
|
|
1828
|
+
text: str = pydantic.Field(
|
|
1829
|
+
description="A short text description of what the quantity means.",
|
|
1830
|
+
max_length=140,
|
|
1831
|
+
)
|
|
1832
|
+
|
|
1833
|
+
def format_quantity(self) -> str:
|
|
1834
|
+
return self._format_quantity(self.format, self.quantity, unit=self.unit)
|
|
1835
|
+
|
|
1836
|
+
|
|
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
|
+
)
|
|
1728
1850
|
|
|
1729
1851
|
|
|
1730
1852
|
# ---------------------------------------------------------------------------
|
|
@@ -2148,6 +2270,11 @@ __all__ = [
|
|
|
2148
2270
|
"SafetyCase",
|
|
2149
2271
|
"SafetyCaseSpec",
|
|
2150
2272
|
"SchemaAdapter",
|
|
2273
|
+
"Score",
|
|
2274
|
+
"ScoreData",
|
|
2275
|
+
"ScoreSpec",
|
|
2276
|
+
"ScoreMetadata",
|
|
2277
|
+
"ScoreMetadataRefs",
|
|
2151
2278
|
"Status",
|
|
2152
2279
|
"StorageSignedURL",
|
|
2153
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
|