dyff-schema 0.31.2__py3-none-any.whl → 0.33.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/_version.py CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = version = "0.31.2"
2
- __version_tuple__ = version_tuple = (0, 31, 2)
1
+ __version__ = version = "0.33.0"
2
+ __version_tuple__ = version_tuple = (0, 33, 0)
@@ -0,0 +1,4 @@
1
+ # SPDX-FileCopyrightText: 2024 UL Research Institutes
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ from .v0.r1.responses import *
@@ -0,0 +1,183 @@
1
+ # SPDX-FileCopyrightText: 2024 UL Research Institutes
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ from __future__ import annotations
5
+
6
+ import enum
7
+ import hashlib
8
+ from datetime import datetime, timezone
9
+ from typing import Any, Literal, Optional
10
+
11
+ import canonicaljson
12
+ import pydantic
13
+
14
+ from .base import int64
15
+
16
+
17
+ class KnownMediaTypes(str, enum.Enum):
18
+ oci_image_manifest = "application/vnd.oci.image.manifest.v1+json"
19
+ oci_image_config = "application/vnd.oci.image.config.v1+json"
20
+ oci_image_layer_tar = "application/vnd.oci.image.layer.v1.tar"
21
+ oci_image_layer_tar_gzip = "application/vnd.oci.image.layer.v1.tar+gzip"
22
+
23
+
24
+ # mypy gets confused because 'dict' is the name of a method in DyffBaseModel
25
+ _ModelAsDict = dict[str, Any]
26
+
27
+
28
+ class _OCISchemaBaseModel(pydantic.BaseModel):
29
+ def model_dump( # type: ignore [override]
30
+ self, *, by_alias: bool = True, exclude_none: bool = True, **kwargs
31
+ ) -> _ModelAsDict:
32
+ return super().model_dump(
33
+ by_alias=by_alias, exclude_none=exclude_none, **kwargs
34
+ )
35
+
36
+ def model_dump_json( # type: ignore [override]
37
+ self, *, by_alias: bool = True, exclude_none: bool = True, **kwargs
38
+ ) -> str:
39
+ return super().model_dump_json(
40
+ by_alias=by_alias, exclude_none=exclude_none, **kwargs
41
+ )
42
+
43
+ def dict(
44
+ self, *, by_alias: bool = True, exclude_none: bool = True, **kwargs
45
+ ) -> _ModelAsDict:
46
+ return self.model_dump(by_alias=by_alias, exclude_none=exclude_none, **kwargs)
47
+
48
+ def json(
49
+ self, *, by_alias: bool = True, exclude_none: bool = True, **kwargs
50
+ ) -> str:
51
+ return self.model_dump_json(
52
+ by_alias=by_alias, exclude_none=exclude_none, **kwargs
53
+ )
54
+
55
+ @pydantic.model_validator(mode="after")
56
+ def _ensure_datetime_timezone_utc(cls, values):
57
+ for field_name, field_value in values.__dict__.items():
58
+ if isinstance(field_value, datetime):
59
+ if field_value.tzinfo is None:
60
+ # Set UTC timezone for naive datetime
61
+ setattr(
62
+ values, field_name, field_value.replace(tzinfo=timezone.utc)
63
+ )
64
+ elif field_value.tzinfo != timezone.utc:
65
+ # Convert to UTC timezone
66
+ setattr(values, field_name, field_value.astimezone(timezone.utc))
67
+ return values
68
+
69
+
70
+ class _DigestMixin(pydantic.BaseModel):
71
+ def digest(self) -> str:
72
+ obj = self.model_dump(mode="json")
73
+ h = hashlib.sha256(usedforsecurity=False)
74
+ for chunk in canonicaljson.iterencode_canonical_json(obj):
75
+ h.update(chunk)
76
+ return "sha256:{}".format(h.hexdigest())
77
+
78
+
79
+ class Platform(_OCISchemaBaseModel):
80
+ architecture: str
81
+ os: str
82
+ os_version: Optional[str] = pydantic.Field(alias="os.version", default=None)
83
+ os_features: Optional[list[str]] = pydantic.Field(alias="os.features", default=None)
84
+ variant: Optional[str] = pydantic.Field(default=None)
85
+
86
+
87
+ class Descriptor(_OCISchemaBaseModel):
88
+ """
89
+ https://github.com/opencontainers/image-spec/blob/v1.1.1/descriptor.md
90
+ """
91
+
92
+ mediaType: str = pydantic.Field()
93
+ digest: str = pydantic.Field()
94
+ size: int64() = pydantic.Field( # type: ignore
95
+ description="This REQUIRED property specifies the size, in bytes,"
96
+ " of the raw content. This property exists so that a client"
97
+ " will have an expected size for the content before processing."
98
+ " If the length of the retrieved content does not match"
99
+ " the specified length, the content SHOULD NOT be trusted."
100
+ )
101
+ urls: Optional[list[str]] = pydantic.Field(default=None)
102
+ annotations: Optional[dict[str, str]] = pydantic.Field(default=None)
103
+ data: Optional[str] = pydantic.Field(default=None)
104
+ artifactType: Optional[str] = pydantic.Field(default=None)
105
+
106
+ @staticmethod
107
+ def empty() -> Descriptor:
108
+ """
109
+ https://github.com/opencontainers/image-spec/blob/v1.1.1/manifest.md#guidance-for-an-empty-descriptor
110
+ """
111
+ return Descriptor.model_validate(
112
+ {
113
+ "mediaType": "application/vnd.oci.empty.v1+json",
114
+ "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
115
+ "size": 2,
116
+ "data": "e30=",
117
+ }
118
+ )
119
+
120
+
121
+ class ImageDescriptor(Descriptor):
122
+ platform: Platform
123
+
124
+
125
+ class ExecutionParameters(_OCISchemaBaseModel):
126
+ # TODO
127
+ pass
128
+
129
+
130
+ class RootFS(_OCISchemaBaseModel):
131
+ type_: Literal["layers"] = pydantic.Field(alias="type", default="layers")
132
+ diff_ids: list[str] = pydantic.Field()
133
+
134
+
135
+ class HistoryEntry(_OCISchemaBaseModel):
136
+ created: Optional[str] = pydantic.Field(default=None)
137
+ author: Optional[str] = pydantic.Field(default=None)
138
+ created_by: Optional[str] = pydantic.Field(default=None)
139
+ comment: Optional[str] = pydantic.Field(default=None)
140
+ empty_layer: Optional[bool] = pydantic.Field(default=None)
141
+
142
+
143
+ class ImageConfig(Platform, _DigestMixin):
144
+ """
145
+ https://github.com/opencontainers/image-spec/blob/v1.1.1/config.md
146
+ """
147
+
148
+ created: Optional[str] = pydantic.Field(default=None)
149
+ author: Optional[str] = pydantic.Field(default=None)
150
+ config: Optional[ExecutionParameters] = pydantic.Field(default=None)
151
+ rootfs: RootFS
152
+ history: Optional[list[HistoryEntry]] = pydantic.Field(default=None)
153
+
154
+
155
+ class ImageManifest(_OCISchemaBaseModel):
156
+ schemaVersion: Literal["2"] = "2"
157
+ mediaType: Literal["application/vnd.oci.image.manifest.v1+json"] = (
158
+ "application/vnd.oci.image.manifest.v1+json"
159
+ )
160
+ artifactType: Optional[str] = pydantic.Field(default=None)
161
+ config: Descriptor = pydantic.Field(default_factory=Descriptor.empty)
162
+ layers: list[Descriptor] = pydantic.Field(
163
+ default_factory=lambda: [Descriptor.empty()]
164
+ )
165
+ subject: Optional[Descriptor] = pydantic.Field(default=None)
166
+ annotations: Optional[dict[str, str]] = pydantic.Field(default=None)
167
+
168
+ def is_image_manifest(self) -> bool:
169
+ return self.artifactType is None
170
+
171
+ def is_artifact_manifest(self) -> bool:
172
+ return self.artifactType is not None
173
+
174
+ @pydantic.model_validator(mode="after")
175
+ def validate_types(self):
176
+ if self.artifactType is None:
177
+ if self.config.mediaType != KnownMediaTypes.oci_image_config.value:
178
+ raise ValueError(
179
+ ".config.mediaType must be"
180
+ f"{KnownMediaTypes.oci_image_config.value}"
181
+ " if .artifactType is unspecified"
182
+ )
183
+ return self
@@ -33,6 +33,7 @@ from typing_extensions import Annotated, TypeAlias
33
33
 
34
34
  from ... import named_data_schema, product_schema
35
35
  from ...version import SomeSchemaVersion
36
+ from . import oci
36
37
  from .base import DyffSchemaBaseModel
37
38
  from .dataset import arrow, make_item_type, make_response_type
38
39
  from .version import SCHEMA_VERSION, SchemaVersion
@@ -193,6 +194,7 @@ class Entities(str, enum.Enum):
193
194
 
194
195
  Account = "Account"
195
196
  Analysis = "Analysis"
197
+ Artifact = "Artifact"
196
198
  Audit = "Audit"
197
199
  AuditProcedure = "AuditProcedure"
198
200
  Concern = "Concern"
@@ -220,6 +222,7 @@ class Resources(str, enum.Enum):
220
222
  """The resource names corresponding to entities that have API endpoints."""
221
223
 
222
224
  Analysis = "analyses"
225
+ Artifact = "artifacts"
223
226
  Audit = "audits"
224
227
  AuditProcedure = "auditprocedures"
225
228
  Concern = "concerns"
@@ -266,6 +269,7 @@ class Resources(str, enum.Enum):
266
269
 
267
270
  EntityKindLiteral = Literal[
268
271
  "Analysis",
272
+ "Artifact",
269
273
  "Audit",
270
274
  "AuditProcedure",
271
275
  "DataSource",
@@ -488,6 +492,7 @@ class DyffEntityMetadata(DyffSchemaBaseModel):
488
492
  class DyffEntity(Status, Labeled, SchemaVersion, DyffModelWithID):
489
493
  kind: Literal[
490
494
  "Analysis",
495
+ "Artifact",
491
496
  "Audit",
492
497
  "AuditProcedure",
493
498
  "DataSource",
@@ -829,8 +834,10 @@ class Digest(DyffSchemaBaseModel):
829
834
  )
830
835
 
831
836
 
837
+ # TODO: (schema-v1) Rename this to "File" or something -- reserve Artifact
838
+ # for OCI artifacts.
832
839
  class Artifact(DyffSchemaBaseModel):
833
- # TODO: In v1, rename this to 'contentType' or something and commit to making it the MIME type
840
+ # TODO: (schema-v1) Rename this to 'contentType' or something and commit to making it the MIME type
834
841
  kind: Optional[str] = pydantic.Field(
835
842
  default=None, description="The kind of artifact"
836
843
  )
@@ -1122,6 +1129,10 @@ class ModelSource(DyffSchemaBaseModel):
1122
1129
  )
1123
1130
 
1124
1131
 
1132
+ class ContainerImage(DyffSchemaBaseModel):
1133
+ pass
1134
+
1135
+
1125
1136
  class AcceleratorGPU(DyffSchemaBaseModel):
1126
1137
  hardwareTypes: list[str] = pydantic.Field(
1127
1138
  min_length=1,
@@ -2130,6 +2141,25 @@ class Score(ScoreData):
2130
2141
  id: str = pydantic.Field(description="Unique identifier of the entity")
2131
2142
 
2132
2143
 
2144
+ # ---------------------------------------------------------------------------
2145
+ # OCI artifacts
2146
+
2147
+
2148
+ # TODO: (schema-v1) Rename this to Artifact
2149
+ class OCIArtifact(Documented, DyffEntity):
2150
+ kind: Literal["Artifact"] = Entities.Artifact.value
2151
+
2152
+ manifest: oci.ImageManifest = pydantic.Field(
2153
+ description="The OCI image manifest of the artifact"
2154
+ )
2155
+
2156
+ def dependencies(self) -> list[str]:
2157
+ return []
2158
+
2159
+ def resource_allocation(self) -> Optional[ResourceAllocation]:
2160
+ return None
2161
+
2162
+
2133
2163
  # ---------------------------------------------------------------------------
2134
2164
  # Status enumerations
2135
2165
 
@@ -2372,6 +2402,7 @@ def is_status_success(status: str) -> bool:
2372
2402
 
2373
2403
  _ENTITY_CLASS = {
2374
2404
  Entities.Analysis: Analysis,
2405
+ Entities.Artifact: OCIArtifact,
2375
2406
  Entities.Audit: Audit,
2376
2407
  Entities.AuditProcedure: AuditProcedure,
2377
2408
  Entities.Dataset: Dataset,
@@ -2406,6 +2437,7 @@ _DyffEntityTypeRevisable = Union[
2406
2437
  Method,
2407
2438
  Model,
2408
2439
  Module,
2440
+ OCIArtifact,
2409
2441
  Report,
2410
2442
  SafetyCase,
2411
2443
  UseCase,
@@ -2579,6 +2611,7 @@ __all__ = [
2579
2611
  "ModelStorage",
2580
2612
  "Module",
2581
2613
  "ModuleBase",
2614
+ "OCIArtifact",
2582
2615
  "QueryableDyffEntity",
2583
2616
  "Report",
2584
2617
  "ReportBase",
@@ -21,7 +21,7 @@ from typing import Any, Literal, Optional, Union
21
21
  import pydantic
22
22
 
23
23
  from ... import upcast
24
- from . import commands
24
+ from . import commands, oci
25
25
  from .base import DyffBaseModel, JsonMergePatchSemantics
26
26
  from .platform import (
27
27
  AnalysisBase,
@@ -72,6 +72,20 @@ class DyffRequestBase(SchemaVersion, DyffRequestDefaultValidators):
72
72
  # TODO: (DYFF-223) I think that exclude_unset=True should be the default
73
73
  # for all schema objects, but I'm unsure of the consequences of making
74
74
  # this change and we'll defer it until v1.
75
+ def model_dump( # type: ignore [override]
76
+ self, *, by_alias: bool = True, exclude_unset=True, **kwargs
77
+ ) -> _ModelAsDict:
78
+ return super().model_dump(
79
+ by_alias=by_alias, exclude_unset=exclude_unset, **kwargs
80
+ )
81
+
82
+ def model_dump_json( # type: ignore [override]
83
+ self, *, by_alias: bool = True, exclude_unset=True, **kwargs
84
+ ) -> str:
85
+ return super().model_dump_json(
86
+ by_alias=by_alias, exclude_unset=exclude_unset, **kwargs
87
+ )
88
+
75
89
  def dict(
76
90
  self, *, by_alias: bool = True, exclude_unset=True, **kwargs
77
91
  ) -> _ModelAsDict:
@@ -118,6 +132,10 @@ class AnalysisCreateRequest(DyffEntityCreateRequest, AnalysisBase):
118
132
  return scope
119
133
 
120
134
 
135
+ class ArtifactCreateRequest(DyffEntityCreateRequest):
136
+ manifest: oci.ImageManifest
137
+
138
+
121
139
  class ConcernCreateRequest(DyffEntityCreateRequest, ConcernBase):
122
140
  @pydantic.field_validator("documentation", check_fields=False)
123
141
  def _validate_documentation(
@@ -357,6 +375,10 @@ class _AnalysisProductQueryRequest(DyffEntityQueryRequest):
357
375
  inputs: Optional[str] = pydantic.Field(default=None)
358
376
 
359
377
 
378
+ class ArtifactQueryRequest(DyffEntityQueryRequest):
379
+ name: Optional[str] = pydantic.Field(default=None)
380
+
381
+
360
382
  class AuditQueryRequest(DyffEntityQueryRequest):
361
383
  name: Optional[str] = pydantic.Field(default=None)
362
384
 
@@ -446,6 +468,8 @@ class UseCaseQueryRequest(DyffEntityQueryRequest):
446
468
 
447
469
  __all__ = [
448
470
  "AnalysisCreateRequest",
471
+ "ArtifactCreateRequest",
472
+ "ArtifactQueryRequest",
449
473
  "AuditQueryRequest",
450
474
  "ConcernCreateRequest",
451
475
  "DyffEntityCreateRequest",
@@ -0,0 +1,38 @@
1
+ # SPDX-FileCopyrightText: 2024 UL Research Institutes
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """API response schemas for dyff platform endpoints.
4
+
5
+ These types represent the structured responses returned by dyff API endpoints. They are
6
+ shared between the API server and client libraries to ensure consistent data structures.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import Dict, List
12
+
13
+ import pydantic
14
+
15
+ from .base import DyffSchemaBaseModel
16
+ from .platform import EntityIdentifier
17
+
18
+
19
+ class WorkflowLogEntry(DyffSchemaBaseModel):
20
+ """A single log entry from workflow infrastructure logs."""
21
+
22
+ timestamp: str = pydantic.Field(description="ISO 8601 timestamp")
23
+ message: str = pydantic.Field(description="Log message content")
24
+ labels: Dict[str, str] = pydantic.Field(
25
+ description="Kubernetes labels associated with the log entry"
26
+ )
27
+
28
+
29
+ class WorkflowLogsResponse(DyffSchemaBaseModel):
30
+ """Response from workflow logs endpoint."""
31
+
32
+ workflow: EntityIdentifier = pydantic.Field(
33
+ description="Entity that generated these workflow logs"
34
+ )
35
+ logs: List[WorkflowLogEntry] = pydantic.Field(
36
+ description="Log entries from the workflow execution"
37
+ )
38
+ totalLines: int = pydantic.Field(description="Total number of log lines available")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dyff-schema
3
- Version: 0.31.2
3
+ Version: 0.33.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
@@ -20,6 +20,7 @@ Requires-Python: >=3.10
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
22
  License-File: NOTICE
23
+ Requires-Dist: canonicaljson==2.0.0
23
24
  Requires-Dist: hypothesis
24
25
  Requires-Dist: hypothesis-jsonschema
25
26
  Requires-Dist: jsonpath-ng
@@ -1,5 +1,5 @@
1
1
  dyff/schema/__init__.py,sha256=w7OWDFuyGKd6xt_yllNtKzHahPgywrfU4Ue02psYaMA,2244
2
- dyff/schema/_version.py,sha256=z4vDFHifVJxLq5dzqsXzDAeoUWPxVCuClnP5IuuPB7E,80
2
+ dyff/schema/_version.py,sha256=uTbdsxpcOU7mMXqX3G50NVmPGutL-k0_3StqoCGV-b0,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
@@ -11,6 +11,7 @@ dyff/schema/platform.py,sha256=peHzGGSd5dQ-EFXrWDjBqMUtoOL3iCHxcV3XzW6Rjag,123
11
11
  dyff/schema/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  dyff/schema/quantity.py,sha256=hhS9ybqW_6I--acPhkoZbFWASxFTEs7CUjO4pmpBJ98,3788
13
13
  dyff/schema/requests.py,sha256=euObiC5IRe9fGev9ND--bcysuACNBDhSbZ5kONSaRwE,123
14
+ dyff/schema/responses.py,sha256=9ZAwDppjFzkWXRhPSxDOT5dDo7VbWk1dgNIc000mRPk,124
14
15
  dyff/schema/test.py,sha256=xtXZHqdVi_bjGXFFrd4nU10Y9CiukPyZj03rL84ckD4,119
15
16
  dyff/schema/version.py,sha256=MZhYsYOVmMuZo0R1vl1iSus7zfB8UerDcEgoZg7Ln7s,372
16
17
  dyff/schema/dataset/__init__.py,sha256=P4tOKKiOFaVeh3-Keiwpg9n7VTQUJQVOIVZhm8sdArE,123
@@ -27,8 +28,10 @@ dyff/schema/v0/r1/__init__.py,sha256=L5y8UhRnojerPYHumsxQJRcHCNz8Hj9NM8b47mewMNs
27
28
  dyff/schema/v0/r1/adapters.py,sha256=hpwCSW8lkMkUKCLe0zaMUDu-VS_caSxJvPsECEi_XRA,33069
28
29
  dyff/schema/v0/r1/base.py,sha256=fdhAa4hpbSn7m3U0qha4rG7gJiYUvPR8SaM-mwszoy0,20289
29
30
  dyff/schema/v0/r1/commands.py,sha256=VoThKeIVz4ZQAqBXhb6TVOG6aG4m_Oa0_6Sc4oxyFhs,9801
30
- dyff/schema/v0/r1/platform.py,sha256=7ErqSqPLQD2bIEqnJByktBb7RaQYRkZbqQsofb0dFIM,82736
31
- dyff/schema/v0/r1/requests.py,sha256=C-LX-NAIDgh88xCl3NW7wqLIpurK8SXqmhRnGvy4BM0,17197
31
+ dyff/schema/v0/r1/oci.py,sha256=mvh1BaiRahZbjIbMh7RqZxZjOKZT9GsS1yBpSdPw01Y,6587
32
+ dyff/schema/v0/r1/platform.py,sha256=s1O_mAVfi9owekqYxcjwPI10s3F7RNo8B8WvMunMi4U,83577
33
+ dyff/schema/v0/r1/requests.py,sha256=3XcFcKChubBrxoHCUHkV5GrNl6Ijdbxn4D4UZAAo09g,17965
34
+ dyff/schema/v0/r1/responses.py,sha256=nxy7FPtfw2B_bljz5UGGuSE79HTkDQxKH56AJVmd4Qo,1287
32
35
  dyff/schema/v0/r1/test.py,sha256=X6dUyVd5svcPCI-PBMOAqEfK9jv3bRDvkQTJzwS96c0,10720
33
36
  dyff/schema/v0/r1/version.py,sha256=NONebgcv5Thsw_ymud6PacZdGjV6ndBrmLnap-obcpo,428
34
37
  dyff/schema/v0/r1/dataset/__init__.py,sha256=LbVlkO2asyGYBKk2z49xjJYTM-pu9y9e4eQDXgTDLnM,2553
@@ -40,9 +43,9 @@ dyff/schema/v0/r1/dataset/text.py,sha256=MYG5seGODDryRSCy-g0Unh5dD0HCytmZ3FeElC-
40
43
  dyff/schema/v0/r1/dataset/vision.py,sha256=aIe0fbfM_g3DsrDTdg2K803YKLjZBpurM_VJcJFuZLc,369
41
44
  dyff/schema/v0/r1/io/__init__.py,sha256=L5y8UhRnojerPYHumsxQJRcHCNz8Hj9NM8b47mewMNs,92
42
45
  dyff/schema/v0/r1/io/vllm.py,sha256=vWyLg-susbg0JDfv6VExBpgFdU2GHP2a14ChOdbckvs,5321
43
- dyff_schema-0.31.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
44
- dyff_schema-0.31.2.dist-info/licenses/NOTICE,sha256=YONACu0s_Ui6jNi-wtEsVQbTU1JIkh8wvLH6d1-Ni_w,43
45
- dyff_schema-0.31.2.dist-info/METADATA,sha256=EXu4JKKOiya1Q3PvC6B2myJr2VrrlcfV91LB2XGU4B4,3632
46
- dyff_schema-0.31.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
47
- dyff_schema-0.31.2.dist-info/top_level.txt,sha256=9e3VVdeX73t_sUJOPQPCcGtYO1JhoErhHIi3WoWGcFI,5
48
- dyff_schema-0.31.2.dist-info/RECORD,,
46
+ dyff_schema-0.33.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
47
+ dyff_schema-0.33.0.dist-info/licenses/NOTICE,sha256=YONACu0s_Ui6jNi-wtEsVQbTU1JIkh8wvLH6d1-Ni_w,43
48
+ dyff_schema-0.33.0.dist-info/METADATA,sha256=XUEtF3Dgk_LSI4YKUPZp5RJzKvzx7nv7_Jxp30ic3W0,3668
49
+ dyff_schema-0.33.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
50
+ dyff_schema-0.33.0.dist-info/top_level.txt,sha256=9e3VVdeX73t_sUJOPQPCcGtYO1JhoErhHIi3WoWGcFI,5
51
+ dyff_schema-0.33.0.dist-info/RECORD,,