dyff-schema 0.18.0__tar.gz → 0.20.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 (59) hide show
  1. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/.gitlab-ci.yml +2 -2
  2. {dyff_schema-0.18.0/dyff_schema.egg-info → dyff_schema-0.20.0}/PKG-INFO +1 -1
  3. dyff_schema-0.20.0/dyff/schema/dataset/embedding.py +4 -0
  4. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/base.py +4 -1
  5. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/dataset/arrow.py +23 -13
  6. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/dataset/binary.py +5 -1
  7. dyff_schema-0.20.0/dyff/schema/v0/r1/dataset/embedding.py +26 -0
  8. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/platform.py +78 -1
  9. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/requests.py +32 -0
  10. {dyff_schema-0.18.0 → dyff_schema-0.20.0/dyff_schema.egg-info}/PKG-INFO +1 -1
  11. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff_schema.egg-info/SOURCES.txt +2 -0
  12. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/.gitignore +0 -0
  13. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/.licenserc.yaml +0 -0
  14. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/.pre-commit-config.yaml +0 -0
  15. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/.prettierignore +0 -0
  16. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/.secrets.baseline +0 -0
  17. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/CODE_OF_CONDUCT.md +0 -0
  18. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/LICENSE +0 -0
  19. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/NOTICE +0 -0
  20. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/README.md +0 -0
  21. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/__init__.py +0 -0
  22. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/adapters.py +0 -0
  23. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/annotations.py +0 -0
  24. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/base.py +0 -0
  25. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/copydoc.py +0 -0
  26. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/dataset/__init__.py +0 -0
  27. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/dataset/arrow.py +0 -0
  28. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/dataset/binary.py +0 -0
  29. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/dataset/classification.py +0 -0
  30. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/dataset/text.py +0 -0
  31. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/dataset/vision.py +0 -0
  32. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/errors.py +0 -0
  33. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/ids.py +0 -0
  34. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/io/__init__.py +0 -0
  35. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/io/vllm.py +0 -0
  36. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/platform.py +0 -0
  37. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/py.typed +0 -0
  38. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/quantity.py +0 -0
  39. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/requests.py +0 -0
  40. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/test.py +0 -0
  41. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/__init__.py +0 -0
  42. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/__init__.py +0 -0
  43. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/adapters.py +0 -0
  44. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/dataset/__init__.py +0 -0
  45. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/dataset/classification.py +0 -0
  46. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/dataset/text.py +0 -0
  47. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/dataset/vision.py +0 -0
  48. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/io/__init__.py +0 -0
  49. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/io/vllm.py +0 -0
  50. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/test.py +0 -0
  51. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/v0/r1/version.py +0 -0
  52. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff/schema/version.py +0 -0
  53. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff_schema.egg-info/dependency_links.txt +0 -0
  54. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff_schema.egg-info/requires.txt +0 -0
  55. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/dyff_schema.egg-info/top_level.txt +0 -0
  56. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/makefile +0 -0
  57. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/pyproject.toml +0 -0
  58. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/setup.cfg +0 -0
  59. {dyff_schema-0.18.0 → dyff_schema-0.20.0}/tests/test_import.py +0 -0
@@ -12,7 +12,7 @@ include:
12
12
  file:
13
13
  - gitlab-release.yml
14
14
  - project: buildgarden/pipelines/detect-secrets
15
- ref: 0.2.1
15
+ ref: 0.2.2
16
16
  file:
17
17
  - detect-secrets.yml
18
18
  - project: buildgarden/pipelines/prettier
@@ -20,7 +20,7 @@ include:
20
20
  file:
21
21
  - prettier.yml
22
22
  - project: buildgarden/pipelines/python
23
- ref: 0.14.0
23
+ ref: 0.14.1
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.18.0
3
+ Version: 0.20.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
@@ -0,0 +1,4 @@
1
+ # SPDX-FileCopyrightText: 2024 UL Research Institutes
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ from ..v0.r1.dataset.embedding import *
@@ -547,8 +547,11 @@ def uint64(
547
547
  return type("UInt64Value", (UInt64,), namespace)
548
548
 
549
549
 
550
+ _ListElementT = TypeVar("_ListElementT")
551
+
552
+
550
553
  def list_(
551
- item_type: Type[pydantic.BaseModel], *, list_size: Optional[int] = None
554
+ item_type: Type[_ListElementT], *, list_size: Optional[int] = None
552
555
  ) -> Type[list]:
553
556
  if list_size is None:
554
557
  return pydantic.conlist(item_type)
@@ -8,7 +8,7 @@ import functools
8
8
  import inspect
9
9
  import typing
10
10
  import uuid
11
- from typing import Any, Iterable, Optional
11
+ from typing import Any, Iterable, Literal, Optional
12
12
 
13
13
  import pyarrow
14
14
  import pyarrow.dataset
@@ -51,7 +51,10 @@ def make_response_schema(schema: pyarrow.Schema) -> pyarrow.Schema:
51
51
  """Given an Arrow schema, create a new one that has the extra ``ResponseItem``
52
52
  fields added."""
53
53
  response_item_schema = make_response_item_schema(schema)
54
- fields = list(zip(response_item_schema.names, response_item_schema.types))
54
+ fields = [
55
+ pyarrow.field(n, t)
56
+ for n, t in zip(response_item_schema.names, response_item_schema.types)
57
+ ]
55
58
  item_type = pyarrow.struct(fields)
56
59
  responses_type = pyarrow.list_(item_type)
57
60
  return pyarrow.schema(
@@ -65,7 +68,8 @@ def make_response_schema(schema: pyarrow.Schema) -> pyarrow.Schema:
65
68
 
66
69
  def encode_schema(schema: pyarrow.Schema) -> str:
67
70
  """Encode an Arrow schema as a string."""
68
- return binary.encode(schema.serialize())
71
+ # pyarrow.Buffer doesn't satisfy ReadableBuffer but it still works
72
+ return binary.encode(schema.serialize()) # type: ignore[arg-type]
69
73
 
70
74
 
71
75
  def decode_schema(schema: str) -> pyarrow.Schema:
@@ -84,7 +88,7 @@ def subset_schema(schema: pyarrow.Schema, field_names: list[str]) -> pyarrow.Sch
84
88
  return pyarrow.schema(fields)
85
89
 
86
90
 
87
- def arrow_type(annotation: type):
91
+ def arrow_type(annotation: type) -> pyarrow.DataType:
88
92
  """Determine a suitable arrow type for a pydantic model field.
89
93
 
90
94
  Supports primitive types as well as pydantic sub-models, lists, and optional types.
@@ -130,8 +134,7 @@ def arrow_type(annotation: type):
130
134
 
131
135
  if issubclass(annotation, DType):
132
136
  # The dtype is in the metaclass
133
- return type(annotation).dtype # type: ignore
134
- # return pyarrow.from_numpy_dtype(type(annotation).dtype) # type: ignore
137
+ return pyarrow.from_numpy_dtype(type(annotation).dtype) # type: ignore[attr-defined]
135
138
 
136
139
  if annotation == bool:
137
140
  return pyarrow.bool_()
@@ -246,6 +249,7 @@ def _construct_field_docs(
246
249
  if pyarrow.types.is_struct(field.type):
247
250
  children = [field.type.field(i) for i in range(field.type.num_fields)]
248
251
  elif pyarrow.types.is_list(field.type):
252
+ assert isinstance(field.type, pyarrow.ListType)
249
253
  children = [field.type.value_field]
250
254
  else:
251
255
  raise ValueError(f"Unsupported nested type {field.type}")
@@ -275,8 +279,10 @@ def write_dataset(
275
279
  *,
276
280
  output_path: str,
277
281
  feature_schema: pyarrow.Schema,
278
- partition_schema: pyarrow.Schema = None,
279
- existing_data_behavior: str = "overwrite_or_ignore",
282
+ partition_schema: Optional[pyarrow.Schema] = None,
283
+ existing_data_behavior: Literal[
284
+ "error", "overwrite_or_ignore", "delete_matching"
285
+ ] = "overwrite_or_ignore",
280
286
  **kwargs,
281
287
  ):
282
288
  """Creates a ``pyarrow.dataset.Dataset`` from a data generator.
@@ -291,15 +297,19 @@ def write_dataset(
291
297
  existing_data_behavior: Same as ``pyarrow.dataset.write_dataset``, but
292
298
  defaults to ``"overwrite_or_ignore"``, which is typically what we want.
293
299
  """
294
- partitioning = partition_schema and pyarrow.dataset.partitioning(
295
- partition_schema, flavor="hive"
300
+ partitioning = (
301
+ pyarrow.dataset.partitioning(partition_schema, flavor="hive")
302
+ if partition_schema is not None
303
+ else None
296
304
  )
297
305
  pyarrow.dataset.write_dataset(
298
306
  data_generator,
299
307
  output_path,
300
308
  format="parquet",
301
309
  schema=feature_schema,
302
- partitioning=partitioning,
310
+ # Type annotation doesn't include PartitioningFactory even though
311
+ # you're clearly meant to pass the output of partitioning() here
312
+ partitioning=partitioning, # type: ignore[arg-type]
303
313
  existing_data_behavior=existing_data_behavior,
304
314
  **kwargs,
305
315
  )
@@ -326,10 +336,10 @@ def batches(
326
336
  for instance in instances:
327
337
  batch.append(instance)
328
338
  if len(batch) == batch_size:
329
- yield pyarrow.RecordBatch.from_pylist(batch, schema=schema)
339
+ yield pyarrow.RecordBatch.from_pylist(batch, schema=schema) # type: ignore[attr-defined]
330
340
  batch = []
331
341
  if batch: # Final (incomplete) batch
332
- yield pyarrow.RecordBatch.from_pylist(batch, schema=schema)
342
+ yield pyarrow.RecordBatch.from_pylist(batch, schema=schema) # type: ignore[attr-defined]
333
343
 
334
344
 
335
345
  __all__ = [
@@ -3,9 +3,13 @@
3
3
 
4
4
  import base64
5
5
  import hashlib
6
+ import typing
6
7
 
8
+ if typing.TYPE_CHECKING:
9
+ from _typeshed import ReadableBuffer
7
10
 
8
- def encode(data: bytes) -> str:
11
+
12
+ def encode(data: "ReadableBuffer") -> str:
9
13
  return base64.b64encode(data).decode("utf-8")
10
14
 
11
15
 
@@ -0,0 +1,26 @@
1
+ # SPDX-FileCopyrightText: 2024 UL Research Institutes
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ from typing import Type
5
+
6
+ import pydantic
7
+
8
+ from ..base import DyffSchemaBaseModel, FixedWidthFloat, list_
9
+
10
+
11
+ def embedding(
12
+ element_type: Type[FixedWidthFloat], size: int
13
+ ) -> Type[DyffSchemaBaseModel]:
14
+ """Returns a schema type representing a list of fixed-length embedding vectors."""
15
+
16
+ class _Embedding(DyffSchemaBaseModel):
17
+ embedding: list_(element_type, list_size=size) = pydantic.Field( # type: ignore[valid-type]
18
+ description="An embedding vector"
19
+ )
20
+
21
+ return _Embedding
22
+
23
+
24
+ __all__ = [
25
+ "embedding",
26
+ ]
@@ -179,6 +179,14 @@ def summary_maxlen() -> int:
179
179
  return 280
180
180
 
181
181
 
182
+ def entity_id_regex() -> str:
183
+ """An entity ID is a 32-character HEX string.
184
+
185
+ TODO: This doesn't check whether the hex string is a valid UUID.
186
+ """
187
+ return r"^[a-f0-9]{32}$"
188
+
189
+
182
190
  class Entities(str, enum.Enum):
183
191
  """The kinds of entities in the dyff system."""
184
192
 
@@ -186,11 +194,13 @@ class Entities(str, enum.Enum):
186
194
  Analysis = "Analysis"
187
195
  Audit = "Audit"
188
196
  AuditProcedure = "AuditProcedure"
197
+ Concern = "Concern"
189
198
  DataSource = "DataSource"
190
199
  Dataset = "Dataset"
191
200
  Documentation = "Documentation"
192
201
  Evaluation = "Evaluation"
193
202
  Family = "Family"
203
+ Hazard = "Hazard"
194
204
  History = "History"
195
205
  InferenceService = "InferenceService"
196
206
  InferenceSession = "InferenceSession"
@@ -202,6 +212,7 @@ class Entities(str, enum.Enum):
202
212
  Revision = "Revision"
203
213
  SafetyCase = "SafetyCase"
204
214
  Score = "Score"
215
+ UseCase = "UseCase"
205
216
 
206
217
 
207
218
  class Resources(str, enum.Enum):
@@ -210,11 +221,14 @@ class Resources(str, enum.Enum):
210
221
  Analysis = "analyses"
211
222
  Audit = "audits"
212
223
  AuditProcedure = "auditprocedures"
224
+ Concern = "concerns"
213
225
  Dataset = "datasets"
214
226
  DataSource = "datasources"
227
+ Descriptor = "descriptors"
215
228
  Documentation = "documentation"
216
229
  Evaluation = "evaluations"
217
230
  Family = "families"
231
+ Hazard = "hazards"
218
232
  History = "histories"
219
233
  InferenceService = "inferenceservices"
220
234
  InferenceSession = "inferencesessions"
@@ -226,6 +240,7 @@ class Resources(str, enum.Enum):
226
240
  Revision = "revisions"
227
241
  SafetyCase = "safetycases"
228
242
  Score = "scores"
243
+ UseCase = "usecases"
229
244
 
230
245
  Task = "tasks"
231
246
  """
@@ -245,6 +260,9 @@ class Resources(str, enum.Enum):
245
260
  raise ValueError(f"No Resources for Entity kind: {kind}")
246
261
 
247
262
 
263
+ EntityID: TypeAlias = pydantic.constr(regex=entity_id_regex()) # type: ignore
264
+
265
+
248
266
  class DyffModelWithID(DyffSchemaBaseModel):
249
267
  id: str = pydantic.Field(description="Unique identifier of the entity")
250
268
  account: str = pydantic.Field(description="Account that owns the entity")
@@ -385,6 +403,15 @@ class Documented(DyffSchemaBaseModel):
385
403
  )
386
404
 
387
405
 
406
+ class Metadata(DyffSchemaBaseModel):
407
+ pass
408
+
409
+
410
+ class Mutable(DyffSchemaBaseModel):
411
+ etag: str
412
+ lastModificationTime: datetime
413
+
414
+
388
415
  class DyffEntity(Status, Labeled, SchemaVersion, DyffModelWithID):
389
416
  kind: Literal[
390
417
  "Analysis",
@@ -394,6 +421,7 @@ class DyffEntity(Status, Labeled, SchemaVersion, DyffModelWithID):
394
421
  "Dataset",
395
422
  "Evaluation",
396
423
  "Family",
424
+ "Hazard",
397
425
  "History",
398
426
  "InferenceService",
399
427
  "InferenceSession",
@@ -404,6 +432,7 @@ class DyffEntity(Status, Labeled, SchemaVersion, DyffModelWithID):
404
432
  "Report",
405
433
  "Revision",
406
434
  "SafetyCase",
435
+ "UseCase",
407
436
  ]
408
437
 
409
438
  annotations: list[Annotation] = pydantic.Field(
@@ -418,6 +447,10 @@ class DyffEntity(Status, Labeled, SchemaVersion, DyffModelWithID):
418
447
  default=None, description="Resource creation time (assigned by system)"
419
448
  )
420
449
 
450
+ lastTransitionTime: Optional[datetime] = pydantic.Field(
451
+ default=None, description="Time of last (status, reason) change."
452
+ )
453
+
421
454
  @abc.abstractmethod
422
455
  def dependencies(self) -> list[str]:
423
456
  """List of IDs of resources that this resource depends on.
@@ -668,6 +701,32 @@ class History(DyffEntity):
668
701
  )
669
702
 
670
703
 
704
+ class ConcernBase(Documented):
705
+ pass
706
+
707
+
708
+ class Concern(ConcernBase, DyffEntity):
709
+ def label_key(self) -> str:
710
+ return f"{Resources[self.kind].value}.dyff.io/{self.id}"
711
+
712
+ def label_value(self) -> str:
713
+ return "1"
714
+
715
+ def dependencies(self) -> list[str]:
716
+ return []
717
+
718
+ def resource_allocation(self) -> Optional[ResourceAllocation]:
719
+ return None
720
+
721
+
722
+ class Hazard(Concern):
723
+ kind: Literal["Hazard"] = Entities.Hazard.value
724
+
725
+
726
+ class UseCase(Concern):
727
+ kind: Literal["UseCase"] = Entities.UseCase.value
728
+
729
+
671
730
  # ----------------------------------------------------------------------------
672
731
 
673
732
 
@@ -843,7 +902,7 @@ class DataSchema(DyffSchemaBaseModel):
843
902
  def make_output_schema(
844
903
  schema: Union[pyarrow.Schema, Type[DyffSchemaBaseModel], DyffDataSchema],
845
904
  ) -> "DataSchema":
846
- """Construct a complete ``DataSchema`` for inference inputs.
905
+ """Construct a complete ``DataSchema`` for inference outputs.
847
906
 
848
907
  This function will add required special fields for input data and then
849
908
  convert the augmented schema as necessary to populate at least the
@@ -1712,6 +1771,16 @@ class MethodBase(DyffSchemaBaseModel):
1712
1771
  return scores
1713
1772
 
1714
1773
 
1774
+ class MethodMetadata(Metadata):
1775
+ concerns: list[Concern] = pydantic.Field(
1776
+ default_factory=list, description="The Concerns applicable to this Method."
1777
+ )
1778
+
1779
+
1780
+ class ModelMetadata(Metadata):
1781
+ pass
1782
+
1783
+
1715
1784
  class Method(DyffEntity, MethodBase):
1716
1785
  kind: Literal["Method"] = Entities.Method.value
1717
1786
 
@@ -2154,6 +2223,7 @@ DyffEntityTypeExceptRevision = Union[
2154
2223
  Dataset,
2155
2224
  Evaluation,
2156
2225
  Family,
2226
+ Hazard,
2157
2227
  History,
2158
2228
  InferenceService,
2159
2229
  InferenceSession,
@@ -2163,6 +2233,7 @@ DyffEntityTypeExceptRevision = Union[
2163
2233
  Module,
2164
2234
  Report,
2165
2235
  SafetyCase,
2236
+ UseCase,
2166
2237
  ]
2167
2238
 
2168
2239
 
@@ -2217,6 +2288,8 @@ __all__ = [
2217
2288
  "Audit",
2218
2289
  "AuditProcedure",
2219
2290
  "AuditRequirement",
2291
+ "Concern",
2292
+ "ConcernBase",
2220
2293
  "ContainerImageSource",
2221
2294
  "DataSchema",
2222
2295
  "Dataset",
@@ -2228,12 +2301,14 @@ __all__ = [
2228
2301
  "Digest",
2229
2302
  "Documentation",
2230
2303
  "DocumentationBase",
2304
+ "Documented",
2231
2305
  "DyffDataSchema",
2232
2306
  "DyffEntity",
2233
2307
  "DyffEntityType",
2234
2308
  "DyffModelWithID",
2235
2309
  "DyffSchemaBaseModel",
2236
2310
  "Entities",
2311
+ "EntityID",
2237
2312
  "Evaluation",
2238
2313
  "EvaluationBase",
2239
2314
  "ExtractorStep",
@@ -2247,6 +2322,7 @@ __all__ = [
2247
2322
  "ForeignMethod",
2248
2323
  "ForeignModel",
2249
2324
  "Frameworks",
2325
+ "Hazard",
2250
2326
  "History",
2251
2327
  "Identity",
2252
2328
  "InferenceInterface",
@@ -2317,6 +2393,7 @@ __all__ = [
2317
2393
  "StorageSignedURL",
2318
2394
  "TagName",
2319
2395
  "TaskSchema",
2396
+ "UseCase",
2320
2397
  "entity_class",
2321
2398
  "JobStatus",
2322
2399
  "EntityStatus",
@@ -14,6 +14,7 @@ in response.
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
+ import re
17
18
  from datetime import datetime
18
19
  from typing import Optional, Union
19
20
 
@@ -22,6 +23,8 @@ import pydantic
22
23
  from .base import DyffBaseModel
23
24
  from .platform import (
24
25
  AnalysisBase,
26
+ AnalysisScope,
27
+ ConcernBase,
25
28
  DatasetBase,
26
29
  DataView,
27
30
  DocumentationBase,
@@ -70,6 +73,29 @@ class AnalysisCreateRequest(DyffEntityCreateRequest, AnalysisBase):
70
73
 
71
74
  method: str = pydantic.Field(description="Method ID")
72
75
 
76
+ @pydantic.validator("scope", check_fields=False)
77
+ def _validate_scope(cls, scope: AnalysisScope) -> AnalysisScope:
78
+ # TODO: This has to be a validator function because we can't apply the
79
+ # regex contraint to AnalysisScope, since there are already entities
80
+ # with invalid IDs in the data store. Fix in Schema v1.
81
+ uuid4 = r"^[0-9a-f]{8}[0-9a-f]{4}[4][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}$"
82
+ id_pattern = re.compile(uuid4)
83
+ if scope.dataset is not None and not re.match(id_pattern, scope.dataset):
84
+ raise ValueError("scope.dataset must be an entity ID")
85
+ if scope.evaluation is not None and not re.match(id_pattern, scope.evaluation):
86
+ raise ValueError("scope.evaluation must be an entity ID")
87
+ if scope.inferenceService is not None and not re.match(
88
+ id_pattern, scope.inferenceService
89
+ ):
90
+ raise ValueError("scope.inferenceService must be an entity ID")
91
+ if scope.model is not None and not re.match(id_pattern, scope.model):
92
+ raise ValueError("scope.model must be an entity ID")
93
+ return scope
94
+
95
+
96
+ class ConcernCreateRequest(DyffEntityCreateRequest, ConcernBase):
97
+ pass
98
+
73
99
 
74
100
  class DatasetCreateRequest(DyffEntityCreateRequest, DatasetBase):
75
101
  pass
@@ -309,9 +335,14 @@ class ScoreQueryRequest(DyffRequestDefaultValidators):
309
335
  model: Optional[str] = pydantic.Field(default=None)
310
336
 
311
337
 
338
+ class UseCaseQueryRequest(DyffEntityQueryRequest):
339
+ pass
340
+
341
+
312
342
  __all__ = [
313
343
  "AnalysisCreateRequest",
314
344
  "AuditQueryRequest",
345
+ "ConcernCreateRequest",
315
346
  "DyffEntityCreateRequest",
316
347
  "DyffEntityQueryRequest",
317
348
  "DyffRequestBase",
@@ -343,4 +374,5 @@ __all__ = [
343
374
  "ReportQueryRequest",
344
375
  "SafetyCaseQueryRequest",
345
376
  "ScoreQueryRequest",
377
+ "UseCaseQueryRequest",
346
378
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dyff-schema
3
- Version: 0.18.0
3
+ Version: 0.20.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
@@ -27,6 +27,7 @@ dyff/schema/dataset/__init__.py
27
27
  dyff/schema/dataset/arrow.py
28
28
  dyff/schema/dataset/binary.py
29
29
  dyff/schema/dataset/classification.py
30
+ dyff/schema/dataset/embedding.py
30
31
  dyff/schema/dataset/text.py
31
32
  dyff/schema/dataset/vision.py
32
33
  dyff/schema/io/__init__.py
@@ -43,6 +44,7 @@ dyff/schema/v0/r1/dataset/__init__.py
43
44
  dyff/schema/v0/r1/dataset/arrow.py
44
45
  dyff/schema/v0/r1/dataset/binary.py
45
46
  dyff/schema/v0/r1/dataset/classification.py
47
+ dyff/schema/v0/r1/dataset/embedding.py
46
48
  dyff/schema/v0/r1/dataset/text.py
47
49
  dyff/schema/v0/r1/dataset/vision.py
48
50
  dyff/schema/v0/r1/io/__init__.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes