dyff-schema 0.30.0__tar.gz → 0.31.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.
Files changed (65) hide show
  1. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/.gitlab-ci.yml +7 -3
  2. {dyff_schema-0.30.0/dyff_schema.egg-info → dyff_schema-0.31.0}/PKG-INFO +2 -3
  3. dyff_schema-0.31.0/dyff/schema/_version.py +2 -0
  4. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/base.py +2 -4
  5. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/dataset/arrow.py +52 -26
  6. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/platform.py +12 -1
  7. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/requests.py +2 -1
  8. {dyff_schema-0.30.0 → dyff_schema-0.31.0/dyff_schema.egg-info}/PKG-INFO +2 -3
  9. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/pyproject.toml +1 -2
  10. dyff_schema-0.30.0/dyff/schema/_version.py +0 -2
  11. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/.gitignore +0 -0
  12. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/.idea/dyff-schema.iml +0 -0
  13. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/.licenserc.yaml +0 -0
  14. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/.pre-commit-config.yaml +0 -0
  15. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/.prettierignore +0 -0
  16. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/.secrets.baseline +0 -0
  17. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/CODE_OF_CONDUCT.md +0 -0
  18. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/LICENSE +0 -0
  19. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/NOTICE +0 -0
  20. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/README.md +0 -0
  21. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/__init__.py +0 -0
  22. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/adapters.py +0 -0
  23. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/annotations.py +0 -0
  24. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/base.py +0 -0
  25. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/commands.py +0 -0
  26. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/copydoc.py +0 -0
  27. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/dataset/__init__.py +0 -0
  28. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/dataset/arrow.py +0 -0
  29. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/dataset/binary.py +0 -0
  30. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/dataset/classification.py +0 -0
  31. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/dataset/embedding.py +0 -0
  32. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/dataset/text.py +0 -0
  33. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/dataset/vision.py +0 -0
  34. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/errors.py +0 -0
  35. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/ids.py +0 -0
  36. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/io/__init__.py +0 -0
  37. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/io/vllm.py +0 -0
  38. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/platform.py +0 -0
  39. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/py.typed +0 -0
  40. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/quantity.py +0 -0
  41. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/requests.py +0 -0
  42. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/test.py +0 -0
  43. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/__init__.py +0 -0
  44. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/__init__.py +0 -0
  45. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/adapters.py +0 -0
  46. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/commands.py +0 -0
  47. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/dataset/__init__.py +0 -0
  48. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/dataset/binary.py +0 -0
  49. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/dataset/classification.py +0 -0
  50. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/dataset/embedding.py +0 -0
  51. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/dataset/text.py +0 -0
  52. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/dataset/vision.py +0 -0
  53. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/io/__init__.py +0 -0
  54. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/io/vllm.py +0 -0
  55. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/test.py +0 -0
  56. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/v0/r1/version.py +0 -0
  57. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff/schema/version.py +0 -0
  58. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff_schema.egg-info/SOURCES.txt +0 -0
  59. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff_schema.egg-info/dependency_links.txt +0 -0
  60. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff_schema.egg-info/requires.txt +0 -0
  61. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/dyff_schema.egg-info/top_level.txt +0 -0
  62. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/makefile +0 -0
  63. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/setup.cfg +0 -0
  64. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/tests/test_adapters.py +0 -0
  65. {dyff_schema-0.30.0 → dyff_schema-0.31.0}/tests/test_import.py +0 -0
@@ -8,7 +8,7 @@ stages:
8
8
 
9
9
  include:
10
10
  - project: saferatday0/library/gitlab
11
- ref: 0.7.0
11
+ ref: 0.16.0
12
12
  file:
13
13
  - gitlab-release.yml
14
14
  - project: saferatday0/library/detect-secrets
@@ -20,7 +20,7 @@ include:
20
20
  file:
21
21
  - prettier.yml
22
22
  - project: saferatday0/library/python
23
- ref: 0.20.0
23
+ ref: 0.21.0
24
24
  file:
25
25
  - python-autoflake.yml
26
26
  - python-black.yml
@@ -37,6 +37,10 @@ include:
37
37
  file:
38
38
  - license-eye-header-check.yml
39
39
 
40
+ # Override image to use Go 1.24 to avoid golang.org/x/tools bug
41
+ license-eye-header-check:
42
+ image: "${CONTAINER_PROXY}golang:1.24-alpine"
43
+
40
44
  variables:
41
45
  PYTHON_PACKAGE: dyff/schema
42
46
  PYTHON_REQUIREMENTS: .
@@ -58,4 +62,4 @@ python-twine-upload-pypi:
58
62
  python-pytest:
59
63
  parallel:
60
64
  matrix:
61
- - PYTHON_VERSION: ['3.9', '3.10', '3.11', '3.12']
65
+ - PYTHON_VERSION: ['3.10', '3.11', '3.12']
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dyff-schema
3
- Version: 0.30.0
3
+ Version: 0.31.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
@@ -12,12 +12,11 @@ Classifier: Intended Audience :: Science/Research
12
12
  Classifier: License :: OSI Approved :: Apache Software License
13
13
  Classifier: Operating System :: OS Independent
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.9
16
15
  Classifier: Programming Language :: Python :: 3.10
17
16
  Classifier: Programming Language :: Python :: 3.11
18
17
  Classifier: Programming Language :: Python :: 3.12
19
18
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
- Requires-Python: >=3.9
19
+ Requires-Python: >=3.10
21
20
  Description-Content-Type: text/markdown
22
21
  License-File: LICENSE
23
22
  License-File: NOTICE
@@ -0,0 +1,2 @@
1
+ __version__ = version = "0.31.0"
2
+ __version_tuple__ = version_tuple = (0, 31, 0)
@@ -431,13 +431,11 @@ def list_(
431
431
  item_type: type[_ListElementT], *, list_size: Optional[int] = None
432
432
  ) -> type[list]:
433
433
  if list_size is None:
434
- return Annotated[list[_ListElementT], Field()] # type: ignore [return-value]
434
+ return Annotated[list[item_type], Field()] # type: ignore [return-value, valid-type]
435
435
  else:
436
436
  if list_size <= 0:
437
437
  raise ValueError(f"list_size {list_size} must be > 0")
438
- return Annotated[
439
- list[_ListElementT], Field(min_length=list_size, max_length=list_size)
440
- ] # type: ignore [return-value]
438
+ return Annotated[list[item_type], Field(min_length=list_size, max_length=list_size)] # type: ignore [return-value, valid-type]
441
439
 
442
440
 
443
441
  # mypy gets confused because 'dict' is the name of a method in DyffBaseModel
@@ -7,11 +7,13 @@ from __future__ import annotations
7
7
  import functools
8
8
  import inspect
9
9
  import typing
10
+ import uuid
10
11
  from typing import Any, Iterable, Literal, Optional
11
12
 
12
13
  import pyarrow
13
14
  import pyarrow.dataset
14
15
  import pydantic
16
+ from pydantic.fields import FieldInfo
15
17
 
16
18
  from ..base import DType
17
19
  from . import binary
@@ -90,9 +92,12 @@ def subset_schema(schema: pyarrow.Schema, field_names: list[str]) -> pyarrow.Sch
90
92
 
91
93
 
92
94
  def arrow_type(annotation: type) -> pyarrow.DataType:
93
- """Determine a suitable arrow type for a pydantic model field."""
95
+ """Determine a suitable arrow type for a pydantic model field.
94
96
 
95
- # Handle generic types first (List, Union, etc.)
97
+ Supports primitive types as well as pydantic sub-models, lists, and optional types.
98
+ Numeric types must have appropriate bounds specified, as Arrow cannot represent the
99
+ unbounded integer types used by Python 3.
100
+ """
96
101
  if origin := typing.get_origin(annotation):
97
102
  if origin == list:
98
103
  annotation_args = typing.get_args(annotation)
@@ -114,40 +119,61 @@ def arrow_type(annotation: type) -> pyarrow.DataType:
114
119
  raise ValueError(
115
120
  f"annotation {annotation}: only Optional[T] supported, not general Union"
116
121
  )
117
- return arrow_type(inner_type)
122
+ return arrow_type(inner_type) # All Arrow types are nullable
118
123
 
119
124
  raise NotImplementedError(f"Python type {annotation}")
120
125
 
121
- # Guard against non-types (TypeVars, etc.)
122
- if not isinstance(annotation, type):
123
- return pyarrow.string()
124
-
125
- # Handle custom types
126
- if issubclass(annotation, DType):
127
- # The dtype is in the metaclass
128
- return pyarrow.from_numpy_dtype(type(annotation).dtype) # type: ignore[attr-defined]
126
+ if issubclass(annotation, pydantic.BaseModel):
127
+ subfields = []
128
+ for _name, subfield in annotation.model_fields.items():
129
+ subfields.append(arrow_field(_name, subfield))
130
+ return pyarrow.struct(subfields)
129
131
 
130
132
  # Handle numpy-like types
131
133
  if hasattr(annotation, "dtype"):
132
134
  return pyarrow.from_numpy_dtype(annotation.dtype)
133
135
 
134
- # Handle pydantic models
135
- if issubclass(annotation, pydantic.BaseModel):
136
- subfields = []
137
- for field_name, subfield in annotation.model_fields.items():
138
- subfields.append(arrow_field(field_name, subfield))
139
- return pyarrow.struct(subfields)
136
+ # Handle Annotated list types (e.g., Annotated[list[str], Field(max_length=10)])
137
+ # This covers lists created by our list_() function in base.py which returns
138
+ # Annotated types with Field metadata for length constraints.
139
+ #
140
+ # We need custom logic here because:
141
+ # 1. Standard typing.List doesn't carry Pydantic Field constraints
142
+ # 2. Our list_() function wraps list[T] in Annotated[list[T], Field(...)]
143
+ # to embed validation metadata (min/max length) at the type level
144
+ # 3. PyArrow needs to know these constraints upfront to create proper schemas
145
+ # 4. The nested generic structure requires careful extraction:
146
+ # Annotated[list[str], Field(max_length=10)] needs to become
147
+ # pyarrow.list_(pyarrow.string(), 10)
148
+ if (
149
+ typing.get_origin(annotation) is typing.Annotated
150
+ and typing.get_args(annotation)[0] is list
151
+ ):
152
+ metadata = typing.get_args(annotation)[1:]
153
+ item_type = typing.get_args(typing.get_args(annotation)[0])[0]
154
+ max_length = -1
155
+ for meta in metadata:
156
+ if isinstance(meta, FieldInfo):
157
+ max_length = getattr(meta, "max_length", -1)
158
+ return pyarrow.list_(arrow_type(item_type), max_length)
140
159
 
141
- # Handle built-in types
142
- type_map = {
143
- str: pyarrow.string(),
144
- int: pyarrow.int64(),
145
- float: pyarrow.float64(),
146
- bool: pyarrow.bool_(),
147
- }
160
+ if issubclass(annotation, DType):
161
+ # The dtype is in the metaclass
162
+ return pyarrow.from_numpy_dtype(type(annotation).dtype) # type: ignore[attr-defined]
148
163
 
149
- if annotation in type_map:
150
- return type_map[annotation]
164
+ if annotation == bool:
165
+ return pyarrow.bool_()
166
+ if annotation == bytes:
167
+ return pyarrow.binary()
168
+ if annotation == float:
169
+ return pyarrow.float64()
170
+ if annotation == int:
171
+ raise ValueError("unconstrained integers cannot be represented in Arrow")
172
+ if annotation == uuid.UUID:
173
+ return pyarrow.binary(16)
174
+
175
+ if annotation == str:
176
+ return pyarrow.string()
151
177
 
152
178
  raise NotImplementedError(f"Python type {annotation}")
153
179
 
@@ -1955,11 +1955,20 @@ class Method(DyffEntity, MethodBase):
1955
1955
  return None
1956
1956
 
1957
1957
 
1958
+ class EntityIDMarker:
1959
+ """Marker class to indicate that a field contains an entity ID that supports
1960
+ family@tag resolution."""
1961
+
1962
+
1963
+ # Type alias for entity ID fields that support family@tag resolution
1964
+ EntityIDField: TypeAlias = Annotated[str, EntityIDMarker]
1965
+
1966
+
1958
1967
  class AnalysisInput(DyffSchemaBaseModel):
1959
1968
  keyword: str = pydantic.Field(
1960
1969
  description="The 'keyword' specified for this input in the MethodSpec."
1961
1970
  )
1962
- entity: str = pydantic.Field(
1971
+ entity: EntityIDField = pydantic.Field(
1963
1972
  description="The ID of the entity whose data should be made available as 'keyword'."
1964
1973
  )
1965
1974
 
@@ -2495,6 +2504,8 @@ __all__ = [
2495
2504
  "Entities",
2496
2505
  "EntityID",
2497
2506
  "EntityIdentifier",
2507
+ "EntityIDField",
2508
+ "EntityIDMarker",
2498
2509
  "EntityKindLiteral",
2499
2510
  "Evaluation",
2500
2511
  "EvaluationBase",
@@ -30,6 +30,7 @@ from .platform import (
30
30
  DatasetBase,
31
31
  DataView,
32
32
  DocumentationBase,
33
+ EntityIDField,
33
34
  Evaluation,
34
35
  EvaluationBase,
35
36
  FamilyBase,
@@ -95,7 +96,7 @@ class AnalysisCreateRequest(DyffEntityCreateRequest, AnalysisBase):
95
96
  """An Analysis transforms Datasets, Evaluations, and Measurements into new
96
97
  Measurements or SafetyCases."""
97
98
 
98
- method: str = pydantic.Field(description="Method ID")
99
+ method: EntityIDField = pydantic.Field(description="Method ID")
99
100
 
100
101
  @pydantic.field_validator("scope", check_fields=False)
101
102
  def _validate_scope(cls, scope: AnalysisScope) -> AnalysisScope:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dyff-schema
3
- Version: 0.30.0
3
+ Version: 0.31.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
@@ -12,12 +12,11 @@ Classifier: Intended Audience :: Science/Research
12
12
  Classifier: License :: OSI Approved :: Apache Software License
13
13
  Classifier: Operating System :: OS Independent
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.9
16
15
  Classifier: Programming Language :: Python :: 3.10
17
16
  Classifier: Programming Language :: Python :: 3.11
18
17
  Classifier: Programming Language :: Python :: 3.12
19
18
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
- Requires-Python: >=3.9
19
+ Requires-Python: >=3.10
21
20
  Description-Content-Type: text/markdown
22
21
  License-File: LICENSE
23
22
  License-File: NOTICE
@@ -23,7 +23,6 @@ classifiers=[
23
23
  "License :: OSI Approved :: Apache Software License",
24
24
  "Operating System :: OS Independent",
25
25
  "Programming Language :: Python :: 3",
26
- "Programming Language :: Python :: 3.9",
27
26
  "Programming Language :: Python :: 3.10",
28
27
  "Programming Language :: Python :: 3.11",
29
28
  "Programming Language :: Python :: 3.12",
@@ -52,7 +51,7 @@ license = {"text" = "Apache-2.0"}
52
51
 
53
52
  readme = "README.md"
54
53
 
55
- requires-python = ">=3.9"
54
+ requires-python = ">=3.10"
56
55
 
57
56
  [project.urls]
58
57
  "Home" = "https://gitlab.com/dyff/packages/dyff-schema"
@@ -1,2 +0,0 @@
1
- __version__ = version = "0.30.0"
2
- __version_tuple__ = version_tuple = (0, 30, 0)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes