dyff-schema 0.13.0__tar.gz → 0.15.0__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.

Potentially problematic release.


This version of dyff-schema might be problematic. Click here for more details.

Files changed (57) hide show
  1. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/.gitlab-ci.yml +1 -1
  2. {dyff_schema-0.13.0/dyff_schema.egg-info → dyff_schema-0.15.0}/PKG-INFO +1 -1
  3. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/ids.py +19 -1
  4. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/platform.py +163 -14
  5. {dyff_schema-0.13.0 → dyff_schema-0.15.0/dyff_schema.egg-info}/PKG-INFO +1 -1
  6. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/.gitignore +0 -0
  7. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/.licenserc.yaml +0 -0
  8. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/.pre-commit-config.yaml +0 -0
  9. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/.prettierignore +0 -0
  10. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/.secrets.baseline +0 -0
  11. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/CODE_OF_CONDUCT.md +0 -0
  12. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/LICENSE +0 -0
  13. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/NOTICE +0 -0
  14. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/README.md +0 -0
  15. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/__init__.py +0 -0
  16. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/adapters.py +0 -0
  17. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/annotations.py +0 -0
  18. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/base.py +0 -0
  19. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/copydoc.py +0 -0
  20. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/dataset/__init__.py +0 -0
  21. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/dataset/arrow.py +0 -0
  22. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/dataset/binary.py +0 -0
  23. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/dataset/classification.py +0 -0
  24. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/dataset/text.py +0 -0
  25. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/dataset/vision.py +0 -0
  26. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/errors.py +0 -0
  27. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/io/__init__.py +0 -0
  28. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/io/vllm.py +0 -0
  29. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/platform.py +0 -0
  30. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/py.typed +0 -0
  31. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/quantity.py +0 -0
  32. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/requests.py +0 -0
  33. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/test.py +0 -0
  34. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/__init__.py +0 -0
  35. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/__init__.py +0 -0
  36. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/adapters.py +0 -0
  37. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/base.py +0 -0
  38. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/dataset/__init__.py +0 -0
  39. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/dataset/arrow.py +0 -0
  40. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/dataset/binary.py +0 -0
  41. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/dataset/classification.py +0 -0
  42. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/dataset/text.py +0 -0
  43. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/dataset/vision.py +0 -0
  44. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/io/__init__.py +0 -0
  45. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/io/vllm.py +0 -0
  46. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/requests.py +0 -0
  47. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/test.py +0 -0
  48. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/v0/r1/version.py +0 -0
  49. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff/schema/version.py +0 -0
  50. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff_schema.egg-info/SOURCES.txt +0 -0
  51. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff_schema.egg-info/dependency_links.txt +0 -0
  52. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff_schema.egg-info/requires.txt +0 -0
  53. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/dyff_schema.egg-info/top_level.txt +0 -0
  54. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/makefile +0 -0
  55. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/pyproject.toml +0 -0
  56. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/setup.cfg +0 -0
  57. {dyff_schema-0.13.0 → dyff_schema-0.15.0}/tests/test_import.py +0 -0
@@ -20,7 +20,7 @@ include:
20
20
  file:
21
21
  - prettier.yml
22
22
  - project: buildgarden/pipelines/python
23
- ref: 0.13.0
23
+ ref: 0.14.0
24
24
  file:
25
25
  - python-autoflake.yml
26
26
  - python-black.yml
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dyff-schema
3
- Version: 0.13.0
3
+ Version: 0.15.0
4
4
  Summary: Data models for the Dyff AI auditing platform.
5
5
  Author-email: Digital Safety Research Institute <contact@dsri.org>
6
6
  License: Apache-2.0
@@ -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 uuid.uuid5(uuid.UUID(hex=evaluation_id), str(replication_index)).hex
58
+ return namespaced_id(evaluation_id, str(replication_index))
@@ -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
- # class Analysis(DyffEntity, AnalysisBase):
1689
- # kind: Literal["Analysis"] = Entities.Analysis.value
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
- # method: ForeignMethod = pydantic.Field(
1692
- # description="The analysis Method to run.",
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
- # def dependencies(self) -> list[str]:
1696
- # return [self.method.id] + [x.entity for x in self.inputs]
1828
+ text: str = pydantic.Field(
1829
+ description="A short text description of what the quantity means.",
1830
+ max_length=140,
1831
+ )
1697
1832
 
1698
- # def resource_allocation(self) -> Optional[ResourceAllocation]:
1699
- # return None
1833
+ def format_quantity(self) -> str:
1834
+ return self._format_quantity(self.format, self.quantity, unit=self.unit)
1700
1835
 
1701
1836
 
1702
- # class AnalysisAndOutputs(DyffSchemaBaseModel):
1703
- # analysis: Analysis = pydantic.Field(description="The Analysis entity")
1704
- # outputs: list[AnalysisOutputType] = pydantic.Field(
1705
- # description="Concrete outputs of the Analysis"
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",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dyff-schema
3
- Version: 0.13.0
3
+ Version: 0.15.0
4
4
  Summary: Data models for the Dyff AI auditing platform.
5
5
  Author-email: Digital Safety Research Institute <contact@dsri.org>
6
6
  License: Apache-2.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes