dyff-schema 0.33.1__py3-none-any.whl → 0.34.1__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/_version.py CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = version = "0.33.1"
2
- __version_tuple__ = version_tuple = (0, 33, 1)
1
+ __version__ = version = "0.34.1"
2
+ __version_tuple__ = version_tuple = (0, 34, 1)
dyff/schema/v0/r1/oci.py CHANGED
@@ -181,3 +181,15 @@ class ImageManifest(_OCISchemaBaseModel):
181
181
  " if .artifactType is unspecified"
182
182
  )
183
183
  return self
184
+
185
+
186
+ __all__ = [
187
+ "Descriptor",
188
+ "ExecutionParameters",
189
+ "HistoryEntry",
190
+ "ImageConfig",
191
+ "ImageDescriptor",
192
+ "ImageManifest",
193
+ "Platform",
194
+ "RootFS",
195
+ ]
@@ -24,6 +24,7 @@ import enum
24
24
  import urllib.parse
25
25
  from datetime import datetime
26
26
  from enum import Enum
27
+ from pathlib import Path
27
28
  from typing import Any, Literal, NamedTuple, Optional, Type, Union
28
29
 
29
30
  import pyarrow
@@ -317,6 +318,9 @@ class EntityIdentifier(DyffSchemaBaseModel):
317
318
  description="The .kind of the entity.",
318
319
  )
319
320
 
321
+ def resource_path(self) -> str:
322
+ return f"{Resources.for_kind(Entities(self.kind)).value}/{self.id}"
323
+
320
324
 
321
325
  def LabelKey() -> type[str]:
322
326
  return Annotated[
@@ -1082,6 +1086,32 @@ class Dataset(DyffEntity, DatasetBase):
1082
1086
  return None
1083
1087
 
1084
1088
 
1089
+ # ----------------------------------------------------------------------------
1090
+ # Model
1091
+
1092
+
1093
+ class File(DyffSchemaBaseModel):
1094
+ mediaType: Optional[str] = pydantic.Field(
1095
+ default=None, description="The media type (MIME type) of the file"
1096
+ )
1097
+ path: str = pydantic.Field(
1098
+ description="The relative path of the file within the containing volume"
1099
+ )
1100
+ digest: Digest = pydantic.Field(
1101
+ default_factory=Digest,
1102
+ description="One or more message digests (hashes) of the file data",
1103
+ )
1104
+
1105
+
1106
+ class FileStorageURL(DyffSchemaBaseModel):
1107
+ file: File
1108
+ signedURL: StorageSignedURL
1109
+
1110
+
1111
+ class Volume(DyffSchemaBaseModel):
1112
+ files: list[File] = pydantic.Field(description="A list of files in the volume")
1113
+
1114
+
1085
1115
  class ModelSourceKinds(str, enum.Enum):
1086
1116
  GitLFS = "GitLFS"
1087
1117
  HuggingFaceHub = "HuggingFaceHub"
@@ -1135,10 +1165,6 @@ class ModelSource(DyffSchemaBaseModel):
1135
1165
  )
1136
1166
 
1137
1167
 
1138
- class ContainerImage(DyffSchemaBaseModel):
1139
- pass
1140
-
1141
-
1142
1168
  class AcceleratorGPU(DyffSchemaBaseModel):
1143
1169
  hardwareTypes: list[str] = pydantic.Field(
1144
1170
  min_length=1,
@@ -1160,14 +1186,23 @@ class Accelerator(DyffSchemaBaseModel):
1160
1186
  )
1161
1187
 
1162
1188
 
1189
+ # FIXME: Remove .storage because it's replaced by ScratchVolume, and rename to
1190
+ # ResourceRequirements for consistency with k8s.
1163
1191
  class ModelResources(DyffSchemaBaseModel):
1164
- storage: Quantity = pydantic.Field(
1165
- description="Amount of storage required for packaged model, in k8s Quantity notation",
1192
+ storage: Optional[Quantity] = pydantic.Field(
1193
+ default=None,
1194
+ deprecated=True,
1195
+ description="Storage required for packaged model, in k8s Quantity notation",
1166
1196
  )
1167
1197
 
1168
1198
  memory: Optional[Quantity] = pydantic.Field(
1169
1199
  default=None,
1170
- description="Amount of memory required to run the model on CPU, in k8s Quantity notation",
1200
+ description="Memory, in k8s Quantity notation",
1201
+ )
1202
+
1203
+ cpu: Optional[Quantity] = pydantic.Field(
1204
+ default=None,
1205
+ description="Number of CPUs, in k8s Quantity notation",
1171
1206
  )
1172
1207
 
1173
1208
 
@@ -1181,6 +1216,7 @@ class ModelStorageMedium(str, enum.Enum):
1181
1216
  class ModelArtifactKind(str, enum.Enum):
1182
1217
  HuggingFaceCache = "HuggingFaceCache"
1183
1218
  Mock = "Mock"
1219
+ Volume = "Volume"
1184
1220
 
1185
1221
 
1186
1222
  class ModelArtifactHuggingFaceCache(DyffSchemaBaseModel):
@@ -1200,6 +1236,9 @@ class ModelArtifact(DyffSchemaBaseModel):
1200
1236
  huggingFaceCache: Optional[ModelArtifactHuggingFaceCache] = pydantic.Field(
1201
1237
  default=None, description="Model stored in a HuggingFace cache"
1202
1238
  )
1239
+ volume: Optional[Volume] = pydantic.Field(
1240
+ default=None, description="Model stored as a generic volume"
1241
+ )
1203
1242
 
1204
1243
 
1205
1244
  class ModelStorage(DyffSchemaBaseModel):
@@ -1251,6 +1290,7 @@ class InferenceServiceBuilder(DyffSchemaBaseModel):
1251
1290
 
1252
1291
  class InferenceServiceRunnerKind(str, Enum):
1253
1292
  BENTOML_SERVICE_OPENLLM = "bentoml_service_openllm"
1293
+ CONTAINER = "container"
1254
1294
  HUGGINGFACE = "huggingface"
1255
1295
  MOCK = "mock"
1256
1296
  STANDALONE = "standalone"
@@ -1312,29 +1352,108 @@ class ContainerImageSource(DyffSchemaBaseModel):
1312
1352
  return v
1313
1353
 
1314
1354
 
1315
- class InferenceServiceRunner(DyffSchemaBaseModel):
1316
- kind: InferenceServiceRunnerKind
1355
+ class EnvVar(DyffSchemaBaseModel):
1356
+ name: str
1357
+ value: str
1358
+
1359
+
1360
+ # TODO: ModelResources is deprecated
1361
+ ResourceRequirements = ModelResources
1362
+
1363
+
1364
+ class VolumeMountKind(str, enum.Enum):
1365
+ data = "Data"
1366
+ scratch = "Scratch"
1367
+
1368
+
1369
+ class VolumeMountData(DyffSchemaBaseModel):
1370
+ source: EntityIdentifier = pydantic.Field(
1371
+ description="The Dyff platform resource to mount."
1372
+ " Must be a volume-like entity such as a Model or Dataset."
1373
+ )
1374
+
1317
1375
 
1376
+ class VolumeMountScratch(DyffSchemaBaseModel):
1377
+ capacity: Quantity = pydantic.Field(
1378
+ description="Minimum storage capacity of the Scratch volume."
1379
+ )
1380
+
1381
+
1382
+ class VolumeMount(DyffSchemaBaseModel):
1383
+ kind: VolumeMountKind = pydantic.Field(description="The kind of volume mount.")
1384
+ name: str = pydantic.Field(description="A descriptive name for the mount.")
1385
+ mountPath: Path = pydantic.Field(
1386
+ description="Where to mount the volume in the running container."
1387
+ " Must be an absolute path."
1388
+ )
1389
+ data: Optional[VolumeMountData] = pydantic.Field(
1390
+ default=None, description="Configuration for Data volume mounts."
1391
+ )
1392
+ scratch: Optional[VolumeMountScratch] = pydantic.Field(
1393
+ default=None, description="Configuration for Scratch volume mounts."
1394
+ )
1395
+
1396
+
1397
+ class Container(DyffSchemaBaseModel):
1398
+ """Configuration of a runnable container backed by either an image hosted in an
1399
+ external registyr, or an image artifact hosted in the Dyff system.
1400
+
1401
+ This is mostly a subset of the Kubernetes Container schema.
1402
+ """
1403
+
1404
+ args: Optional[list[str]] = pydantic.Field(
1405
+ default=None,
1406
+ description="Arguments to the entrypoint."
1407
+ " The container image's CMD is used if this is not provided.",
1408
+ )
1409
+ command: Optional[list[str]] = pydantic.Field(
1410
+ default=None,
1411
+ description="Entrypoint array. Not executed within a shell."
1412
+ " The container image's ENTRYPOINT is used if this is not provided.",
1413
+ )
1414
+ env: Optional[list[EnvVar]] = pydantic.Field(
1415
+ default=None,
1416
+ description="List of environment variables to set in the container.",
1417
+ )
1318
1418
  # TODO: (DYFF-421) Make .image required
1319
1419
  image: Optional[ContainerImageSource] = pydantic.Field(
1320
1420
  default=None,
1321
- description="The container image that implements the runner. This field is"
1322
- " optional for schema backwards-compatibility, but creating new"
1323
- " services with image=None will result in an error.",
1421
+ description="The container image that implements the runner."
1422
+ " Exactly one of .image and .imageRef must be set.",
1324
1423
  )
1325
-
1326
- args: Optional[list[str]] = pydantic.Field(
1327
- default=None, description="Command line arguments to forward to the runner"
1424
+ imageRef: Optional[EntityIdentifier] = pydantic.Field(
1425
+ default=None,
1426
+ description="Container image reference. Must be an image artifact"
1427
+ " that has been uploaded to this Dyff instance and is in Ready status."
1428
+ " Exactly one of .image and .imageRef must be set.",
1429
+ )
1430
+ resources: ResourceRequirements = pydantic.Field(
1431
+ description="Compute Resources required by this container."
1432
+ )
1433
+ volumeMounts: Optional[list[VolumeMount]] = pydantic.Field(
1434
+ default=None, description="Volumes to mount into the container's filesystem."
1328
1435
  )
1436
+ workingDir: Optional[Path] = pydantic.Field(
1437
+ default=None,
1438
+ description="Container's working directory. If not specified,"
1439
+ " the container runtime's default will be used,"
1440
+ " which might be configured in the container image.",
1441
+ )
1442
+
1443
+
1444
+ class InferenceServiceRunner(Container):
1445
+ """Configuration of a managed runner to use to run an inference service.
1446
+
1447
+ Using a managed runner simplifies the configuration of inference services backed by
1448
+ models in common formats, such as HuggingFace models.
1449
+ """
1450
+
1451
+ kind: InferenceServiceRunnerKind
1329
1452
 
1330
1453
  accelerator: Optional[Accelerator] = pydantic.Field(
1331
1454
  default=None, description="Optional accelerator hardware to use, per node."
1332
1455
  )
1333
1456
 
1334
- resources: ModelResources = pydantic.Field(
1335
- description="Resource requirements to run the service, per node."
1336
- )
1337
-
1338
1457
  nodes: int = pydantic.Field(
1339
1458
  default=1,
1340
1459
  ge=1,
@@ -1372,7 +1491,9 @@ class InferenceServiceBase(DyffSchemaBaseModel):
1372
1491
 
1373
1492
  # FIXME: (DYFF-261) .runner should be required
1374
1493
  runner: Optional[InferenceServiceRunner] = pydantic.Field(
1375
- default=None, description="Configuration of the Runner used to run the service."
1494
+ default=None,
1495
+ description="Configuration of the managed runner used to run the service."
1496
+ " Only one of .container or .runner may be specified.",
1376
1497
  )
1377
1498
 
1378
1499
  interface: InferenceInterface = pydantic.Field(
@@ -2525,6 +2646,7 @@ __all__ = [
2525
2646
  "AuditRequirement",
2526
2647
  "Concern",
2527
2648
  "ConcernBase",
2649
+ "Container",
2528
2650
  "ContainerImageSource",
2529
2651
  "DataSchema",
2530
2652
  "Dataset",
@@ -2558,6 +2680,8 @@ __all__ = [
2558
2680
  "FamilyMemberBase",
2559
2681
  "FamilyMemberKind",
2560
2682
  "FamilyMembers",
2683
+ "File",
2684
+ "FileStorageURL",
2561
2685
  "ForeignInferenceService",
2562
2686
  "ForeignMethod",
2563
2687
  "ForeignModel",
@@ -2622,6 +2746,7 @@ __all__ = [
2622
2746
  "Report",
2623
2747
  "ReportBase",
2624
2748
  "Resources",
2749
+ "ResourceRequirements",
2625
2750
  "Revision",
2626
2751
  "RevisionData",
2627
2752
  "RevisionMetadata",
@@ -2640,6 +2765,11 @@ __all__ = [
2640
2765
  "TagNameType",
2641
2766
  "TaskSchema",
2642
2767
  "UseCase",
2768
+ "Volume",
2769
+ "VolumeMount",
2770
+ "VolumeMountData",
2771
+ "VolumeMountKind",
2772
+ "VolumeMountScratch",
2643
2773
  "entity_class",
2644
2774
  "JobStatus",
2645
2775
  "EntityStatus",
@@ -170,15 +170,13 @@ class InferenceServiceCreateRequest(DyffEntityCreateRequest, InferenceServiceBas
170
170
  default=None, description="ID of Model backing the service, if applicable"
171
171
  )
172
172
 
173
- # TODO: (DYFF-421) Make .image required and remove this validator
174
- @pydantic.field_validator("image", check_fields=False)
175
- def validate_image_not_none(cls, v):
176
- if v is None:
177
- raise ValueError(
178
- ".image is required for new services; it is defined as Optional"
179
- " for schema backwards-compatibility only"
180
- )
181
- return v
173
+ @pydantic.model_validator(mode="after")
174
+ def check_image_exactly_one(cls, values):
175
+ image = values.image is not None
176
+ imageRef = values.imageRef is not None
177
+ if sum([image, imageRef]) != 1:
178
+ raise ValueError("must specify exactly one of {image, imageRef}")
179
+ return values
182
180
 
183
181
 
184
182
  class InferenceSessionCreateRequest(DyffEntityCreateRequest, InferenceSessionBase):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dyff-schema
3
- Version: 0.33.1
3
+ Version: 0.34.1
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
@@ -1,5 +1,5 @@
1
1
  dyff/schema/__init__.py,sha256=w7OWDFuyGKd6xt_yllNtKzHahPgywrfU4Ue02psYaMA,2244
2
- dyff/schema/_version.py,sha256=HHIr-roQmq7UeIk5vSugBDJZcU-o8m8SQvHIqK6MMEw,80
2
+ dyff/schema/_version.py,sha256=GQtjW4sJxfe7RJUV7BHBKYvYc1MkShUann2GMgbta8E,80
3
3
  dyff/schema/adapters.py,sha256=YMTHv_2VlLGFp-Kqwa6H51hjffHmk8gXjZilHysIF5Q,123
4
4
  dyff/schema/annotations.py,sha256=nE6Jk1PLqlShj8uqjE_EzZC9zYnTDW5AVtQcjysiK8M,10018
5
5
  dyff/schema/base.py,sha256=jvaNtsSZyFfsdUZTcY_U-yfLY5_GyrMxSXhON2R9XR0,119
@@ -28,9 +28,9 @@ dyff/schema/v0/r1/__init__.py,sha256=L5y8UhRnojerPYHumsxQJRcHCNz8Hj9NM8b47mewMNs
28
28
  dyff/schema/v0/r1/adapters.py,sha256=hpwCSW8lkMkUKCLe0zaMUDu-VS_caSxJvPsECEi_XRA,33069
29
29
  dyff/schema/v0/r1/base.py,sha256=fdhAa4hpbSn7m3U0qha4rG7gJiYUvPR8SaM-mwszoy0,20289
30
30
  dyff/schema/v0/r1/commands.py,sha256=VoThKeIVz4ZQAqBXhb6TVOG6aG4m_Oa0_6Sc4oxyFhs,9801
31
- dyff/schema/v0/r1/oci.py,sha256=mvh1BaiRahZbjIbMh7RqZxZjOKZT9GsS1yBpSdPw01Y,6587
32
- dyff/schema/v0/r1/platform.py,sha256=jTATHm8X39owAcepFyOHfMF-sGgHpLMyw1QvHrOj4k4,83871
33
- dyff/schema/v0/r1/requests.py,sha256=3XcFcKChubBrxoHCUHkV5GrNl6Ijdbxn4D4UZAAo09g,17965
31
+ dyff/schema/v0/r1/oci.py,sha256=Jnnu2EBeYQKC-EbKLG60a5z3WwpOuZMogeJ7vQA74bM,6761
32
+ dyff/schema/v0/r1/platform.py,sha256=wNXguW_pFW11zA10jdH9wxI5xA-ZTJdo4yh1MRmsp6Y,88223
33
+ dyff/schema/v0/r1/requests.py,sha256=KW-CvZx1fQYHb0yoJJ-GLIV5wMp9D9x4a_vKOys1UvM,17890
34
34
  dyff/schema/v0/r1/responses.py,sha256=nxy7FPtfw2B_bljz5UGGuSE79HTkDQxKH56AJVmd4Qo,1287
35
35
  dyff/schema/v0/r1/test.py,sha256=X6dUyVd5svcPCI-PBMOAqEfK9jv3bRDvkQTJzwS96c0,10720
36
36
  dyff/schema/v0/r1/version.py,sha256=NONebgcv5Thsw_ymud6PacZdGjV6ndBrmLnap-obcpo,428
@@ -43,9 +43,9 @@ dyff/schema/v0/r1/dataset/text.py,sha256=MYG5seGODDryRSCy-g0Unh5dD0HCytmZ3FeElC-
43
43
  dyff/schema/v0/r1/dataset/vision.py,sha256=aIe0fbfM_g3DsrDTdg2K803YKLjZBpurM_VJcJFuZLc,369
44
44
  dyff/schema/v0/r1/io/__init__.py,sha256=L5y8UhRnojerPYHumsxQJRcHCNz8Hj9NM8b47mewMNs,92
45
45
  dyff/schema/v0/r1/io/vllm.py,sha256=vWyLg-susbg0JDfv6VExBpgFdU2GHP2a14ChOdbckvs,5321
46
- dyff_schema-0.33.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
47
- dyff_schema-0.33.1.dist-info/licenses/NOTICE,sha256=YONACu0s_Ui6jNi-wtEsVQbTU1JIkh8wvLH6d1-Ni_w,43
48
- dyff_schema-0.33.1.dist-info/METADATA,sha256=YokGFmXlheIonCw4hXMicG3rKbMvTrxw1dv65NhYm8Y,3668
49
- dyff_schema-0.33.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
50
- dyff_schema-0.33.1.dist-info/top_level.txt,sha256=9e3VVdeX73t_sUJOPQPCcGtYO1JhoErhHIi3WoWGcFI,5
51
- dyff_schema-0.33.1.dist-info/RECORD,,
46
+ dyff_schema-0.34.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
47
+ dyff_schema-0.34.1.dist-info/licenses/NOTICE,sha256=YONACu0s_Ui6jNi-wtEsVQbTU1JIkh8wvLH6d1-Ni_w,43
48
+ dyff_schema-0.34.1.dist-info/METADATA,sha256=kDoqejAKYpDgEbeaQI-XBWTslr-j1awc0p9oSTAhh2k,3668
49
+ dyff_schema-0.34.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
50
+ dyff_schema-0.34.1.dist-info/top_level.txt,sha256=9e3VVdeX73t_sUJOPQPCcGtYO1JhoErhHIi3WoWGcFI,5
51
+ dyff_schema-0.34.1.dist-info/RECORD,,