amati 0.3.2__py3-none-any.whl → 0.3.4__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.
- amati/_data/files/media-types.json +2 -0
- amati/_data/files/schemes.json +2 -0
- amati/_data/media_types.py +1 -1
- amati/_data/refresh.py +3 -1
- amati/amati.py +12 -12
- amati/fields/uri.py +4 -4
- amati/file_handler.py +2 -2
- amati/grammars/oas.py +3 -3
- amati/model_validators.py +3 -5
- amati/validators/generic.py +2 -7
- amati/validators/oas304.py +4 -4
- amati/validators/oas311.py +3 -3
- {amati-0.3.2.dist-info → amati-0.3.4.dist-info}/METADATA +2 -1
- {amati-0.3.2.dist-info → amati-0.3.4.dist-info}/RECORD +17 -17
- {amati-0.3.2.dist-info → amati-0.3.4.dist-info}/WHEEL +0 -0
- {amati-0.3.2.dist-info → amati-0.3.4.dist-info}/entry_points.txt +0 -0
- {amati-0.3.2.dist-info → amati-0.3.4.dist-info}/licenses/LICENSE +0 -0
amati/_data/files/schemes.json
CHANGED
|
@@ -151,6 +151,7 @@
|
|
|
151
151
|
"ldaps": "Provisional",
|
|
152
152
|
"leaptofrogans": "Permanent",
|
|
153
153
|
"lid": "Provisional",
|
|
154
|
+
"linkid": "Provisional",
|
|
154
155
|
"lorawan": "Provisional",
|
|
155
156
|
"lpa": "Provisional",
|
|
156
157
|
"lvlt": "Provisional",
|
|
@@ -384,6 +385,7 @@
|
|
|
384
385
|
"wss": "Permanent",
|
|
385
386
|
"wtai": "Provisional",
|
|
386
387
|
"wyciwyg": "Provisional",
|
|
388
|
+
"xcompute": "Provisional",
|
|
387
389
|
"xcon": "Permanent",
|
|
388
390
|
"xcon-userid": "Permanent",
|
|
389
391
|
"xfire": "Provisional",
|
amati/_data/media_types.py
CHANGED
|
@@ -8,7 +8,7 @@ DATA_FILE = Path("media-types.json")
|
|
|
8
8
|
DATA_SOURCE: dict[str, str] = {
|
|
9
9
|
"application": "https://www.iana.org/assignments/media-types/application.csv",
|
|
10
10
|
"audio": "https://www.iana.org/assignments/media-types/audio.csv",
|
|
11
|
-
# "example": "currently no valid values",
|
|
11
|
+
# "example": "currently no valid values", # noqa ERA001
|
|
12
12
|
"font": "https://www.iana.org/assignments/media-types/font.csv",
|
|
13
13
|
"haptics": "https://www.iana.org/assignments/media-types/haptics.csv",
|
|
14
14
|
"image": "https://www.iana.org/assignments/media-types/image.csv",
|
amati/_data/refresh.py
CHANGED
|
@@ -157,7 +157,9 @@ def get(data_type: data_types) -> dict[str, JSONValue] | list[JSONValue] | None:
|
|
|
157
157
|
for module_ in to_get:
|
|
158
158
|
module = importlib.import_module(f"amati._data.{module_}")
|
|
159
159
|
|
|
160
|
-
|
|
160
|
+
data_file: Path = current_path / module.DATA_FILE
|
|
161
|
+
|
|
162
|
+
with data_file.open(encoding="utf-8") as f:
|
|
161
163
|
data = json.loads(f.read())
|
|
162
164
|
|
|
163
165
|
if not data:
|
amati/amati.py
CHANGED
|
@@ -132,11 +132,11 @@ def run(
|
|
|
132
132
|
if not error_path.exists():
|
|
133
133
|
error_path.mkdir()
|
|
134
134
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
) as f:
|
|
135
|
+
json_error_file: Path = error_path / error_file.with_suffix(
|
|
136
|
+
error_file.suffix + ".json"
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
with json_error_file.open("w", encoding="utf-8") as f:
|
|
140
140
|
f.write(json.dumps(handled_errors))
|
|
141
141
|
|
|
142
142
|
if html_report:
|
|
@@ -150,11 +150,11 @@ def run(
|
|
|
150
150
|
html_output = template.render(errors=handled_errors)
|
|
151
151
|
|
|
152
152
|
# Save the output to a file
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
"
|
|
156
|
-
|
|
157
|
-
) as f:
|
|
153
|
+
|
|
154
|
+
html_error_file: Path = error_path / error_file.with_suffix(
|
|
155
|
+
error_file.suffix + ".html"
|
|
156
|
+
)
|
|
157
|
+
with html_error_file.open("w", encoding="utf-8") as f:
|
|
158
158
|
f.write(html_output)
|
|
159
159
|
|
|
160
160
|
if result and consistency_check:
|
|
@@ -247,7 +247,7 @@ if __name__ == "__main__":
|
|
|
247
247
|
logger.info("Data refreshed successfully.")
|
|
248
248
|
sys.exit(0)
|
|
249
249
|
except Exception as e:
|
|
250
|
-
logger.error(f"Error refreshing data: {
|
|
250
|
+
logger.error(f"Error refreshing data: {e}")
|
|
251
251
|
sys.exit(1)
|
|
252
252
|
|
|
253
253
|
specification: Path = Path(args.spec)
|
|
@@ -262,7 +262,7 @@ if __name__ == "__main__":
|
|
|
262
262
|
)
|
|
263
263
|
logger.info(f"Specification {specification} processed successfully.")
|
|
264
264
|
except Exception as e:
|
|
265
|
-
logger.error(f"Error processing {specification}, {
|
|
265
|
+
logger.error(f"Error processing {specification}, {e}")
|
|
266
266
|
sys.exit(1)
|
|
267
267
|
|
|
268
268
|
if args.consistency_check and successful_check:
|
amati/fields/uri.py
CHANGED
|
@@ -3,7 +3,7 @@ Validates a URI according to the RFC3986 ABNF grammar
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from enum import Enum
|
|
6
|
-
from typing import Self, cast
|
|
6
|
+
from typing import ClassVar, Self, cast
|
|
7
7
|
|
|
8
8
|
import idna
|
|
9
9
|
from abnf import Node, ParseError, Rule
|
|
@@ -61,7 +61,7 @@ class Scheme(_Str):
|
|
|
61
61
|
|
|
62
62
|
# Look up the scheme in the IANA registry to get status info
|
|
63
63
|
# Returns None if the scheme is not in the registry
|
|
64
|
-
self.status = SCHEMES.get(value
|
|
64
|
+
self.status = SCHEMES.get(value)
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
class URIType(str, Enum):
|
|
@@ -123,7 +123,7 @@ class URI(_Str):
|
|
|
123
123
|
# RFC 3987 Internationalized Resource Identifier (IRI) flag
|
|
124
124
|
is_iri: bool = False
|
|
125
125
|
|
|
126
|
-
_attribute_map: dict[str, str] = {
|
|
126
|
+
_attribute_map: ClassVar[dict[str, str]] = {
|
|
127
127
|
"authority": "authority",
|
|
128
128
|
"iauthority": "authority",
|
|
129
129
|
"host": "host",
|
|
@@ -176,7 +176,7 @@ class URI(_Str):
|
|
|
176
176
|
# an additional return there is a code path in type() that doesn't return a
|
|
177
177
|
# value. It's better to deal with the potential error case than ignore the
|
|
178
178
|
# lack of a return value.
|
|
179
|
-
raise TypeError(f"{
|
|
179
|
+
raise TypeError(f"{self!s} does not have a URI type.") # pragma: no cover
|
|
180
180
|
|
|
181
181
|
def __init__(self, value: str):
|
|
182
182
|
"""
|
amati/file_handler.py
CHANGED
|
@@ -151,7 +151,7 @@ class FileProcessor:
|
|
|
151
151
|
True if the file is gzip-compressed, False otherwise.
|
|
152
152
|
"""
|
|
153
153
|
try:
|
|
154
|
-
with open(
|
|
154
|
+
with file_path.open("rb") as f:
|
|
155
155
|
magic = f.read(2)
|
|
156
156
|
return magic == b"\x1f\x8b"
|
|
157
157
|
except OSError:
|
|
@@ -189,7 +189,7 @@ class FileProcessor:
|
|
|
189
189
|
with gzip.open(file_path, "rt", encoding="utf-8") as f:
|
|
190
190
|
return f.read()
|
|
191
191
|
else:
|
|
192
|
-
with open(
|
|
192
|
+
with file_path.open(encoding="utf-8") as f:
|
|
193
193
|
return f.read()
|
|
194
194
|
|
|
195
195
|
def _get_appropriate_loader(self, file_path: Path) -> FileLoader:
|
amati/grammars/oas.py
CHANGED
|
@@ -36,10 +36,10 @@ class Rule(_Rule):
|
|
|
36
36
|
# reference-token = *( unescaped / escaped )
|
|
37
37
|
# unescaped = %x00-2E / %x30-7D / %x7F-10FFFF
|
|
38
38
|
# ; %x2F ('/') and %x7E ('~') are excluded from 'unescaped'
|
|
39
|
-
# escaped = "~" ( "0" / "1" )
|
|
39
|
+
# escaped = "~" ( "0" / "1" ) # noqa: ERA001
|
|
40
40
|
# ; representing '~' and '/', respectively
|
|
41
41
|
"name = *( CHAR )",
|
|
42
|
-
# token = 1*tchar,
|
|
43
|
-
# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "."
|
|
42
|
+
# token = 1*tchar, # noqa: ERA001
|
|
43
|
+
# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." # noqa: ERA001 E501
|
|
44
44
|
# / "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
|
|
45
45
|
]
|
amati/model_validators.py
CHANGED
|
@@ -154,7 +154,7 @@ def at_least_one_of(
|
|
|
154
154
|
if is_truthy_with_numeric_zero(value):
|
|
155
155
|
return self
|
|
156
156
|
|
|
157
|
-
public_fields = ", ".join(f"{name}" for name in candidates
|
|
157
|
+
public_fields = ", ".join(f"{name}" for name in candidates)
|
|
158
158
|
|
|
159
159
|
msg = f"{public_fields} do not have values, expected at least one."
|
|
160
160
|
Logger.log(
|
|
@@ -245,10 +245,8 @@ def only_one_of(
|
|
|
245
245
|
truthy.append(name)
|
|
246
246
|
|
|
247
247
|
if len(truthy) != 1:
|
|
248
|
-
if truthy
|
|
249
|
-
|
|
250
|
-
else:
|
|
251
|
-
field_string = "none"
|
|
248
|
+
field_string = ", ".join(truthy) if truthy else "none"
|
|
249
|
+
|
|
252
250
|
msg = f"Expected at most one field to have a value, {field_string} did"
|
|
253
251
|
|
|
254
252
|
Logger.log(
|
amati/validators/generic.py
CHANGED
|
@@ -52,10 +52,7 @@ class GenericObject(BaseModel):
|
|
|
52
52
|
# If extra fields aren't allowed log those that aren't going to be added
|
|
53
53
|
# to the model.
|
|
54
54
|
for field in data:
|
|
55
|
-
if (
|
|
56
|
-
field not in self.model_dump().keys()
|
|
57
|
-
and field not in self.get_field_aliases()
|
|
58
|
-
):
|
|
55
|
+
if field not in self.model_dump() and field not in self.get_field_aliases():
|
|
59
56
|
message = f"{field} is not a valid field for {self.__repr_name__()}."
|
|
60
57
|
Logger.log(
|
|
61
58
|
{
|
|
@@ -92,9 +89,7 @@ class GenericObject(BaseModel):
|
|
|
92
89
|
excess_fields: set[str] = set()
|
|
93
90
|
|
|
94
91
|
pattern: re.Pattern[str] = re.compile(self._extra_field_pattern)
|
|
95
|
-
excess_fields.update(
|
|
96
|
-
key for key in self.model_extra.keys() if not pattern.match(key)
|
|
97
|
-
)
|
|
92
|
+
excess_fields.update(key for key in self.model_extra if not pattern.match(key))
|
|
98
93
|
|
|
99
94
|
for field in excess_fields:
|
|
100
95
|
message = f"{field} is not a valid field for {self.__repr_name__()}."
|
amati/validators/oas304.py
CHANGED
|
@@ -239,7 +239,7 @@ class PathsObject(GenericObject):
|
|
|
239
239
|
Special-case specification extensions, which are also allowed.
|
|
240
240
|
"""
|
|
241
241
|
|
|
242
|
-
for field in data
|
|
242
|
+
for field in data:
|
|
243
243
|
# Specification extensions
|
|
244
244
|
if field.startswith("x-"):
|
|
245
245
|
continue
|
|
@@ -700,7 +700,7 @@ class SchemaObject(GenericObject):
|
|
|
700
700
|
if isinstance(type_val, str) and type_val != "null":
|
|
701
701
|
schema_dict["type"] = [type_val, "null"]
|
|
702
702
|
elif isinstance(type_val, list) and "null" not in type_val:
|
|
703
|
-
schema_dict["type"] = type_val
|
|
703
|
+
schema_dict["type"] = [*type_val, ["null"]]
|
|
704
704
|
|
|
705
705
|
# 2. Validate the schema structure using jsonschema's meta-schema
|
|
706
706
|
# Get the right validator based on the declared $schema or default
|
|
@@ -748,7 +748,7 @@ class OAuthFlowObject(GenericObject):
|
|
|
748
748
|
authorizationUrl: URI | None = None
|
|
749
749
|
tokenUrl: URI | None = None
|
|
750
750
|
refreshUrl: URI | None = None
|
|
751
|
-
scopes: dict[str, str] = {}
|
|
751
|
+
scopes: dict[str, str] = Field(default={})
|
|
752
752
|
_reference_uri: ClassVar[str] = (
|
|
753
753
|
"https://spec.openapis.org/oas/v3.0.4.html#oauth-flow-object"
|
|
754
754
|
)
|
|
@@ -956,7 +956,7 @@ class ComponentsObject(GenericObject):
|
|
|
956
956
|
f"Invalid type for '{field_name}': expected dict, got {type(value)}"
|
|
957
957
|
)
|
|
958
958
|
|
|
959
|
-
for key in value
|
|
959
|
+
for key in value:
|
|
960
960
|
if not re.match(pattern, key):
|
|
961
961
|
raise ValueError(
|
|
962
962
|
f"Invalid key '{key}' in '{field_name}': must match pattern {pattern}" # noqa: E501
|
amati/validators/oas311.py
CHANGED
|
@@ -104,7 +104,7 @@ class LicenceObject(GenericObject):
|
|
|
104
104
|
except AmatiValueError:
|
|
105
105
|
Logger.log(
|
|
106
106
|
{
|
|
107
|
-
"msg": f"{
|
|
107
|
+
"msg": f"{self.url} is not a valid SPDX URL",
|
|
108
108
|
"type": "warning",
|
|
109
109
|
"loc": (self.__class__.__name__,),
|
|
110
110
|
"input": self.url,
|
|
@@ -376,7 +376,7 @@ class SchemaObject(GenericObject):
|
|
|
376
376
|
if isinstance(type_val, str) and type_val != "null":
|
|
377
377
|
schema_dict["type"] = [type_val, "null"]
|
|
378
378
|
elif isinstance(type_val, list) and "null" not in type_val:
|
|
379
|
-
schema_dict["type"] = type_val
|
|
379
|
+
schema_dict["type"] = [*type_val, ["null"]]
|
|
380
380
|
|
|
381
381
|
# 2. Validate the schema structure using jsonschema's meta-schema
|
|
382
382
|
# Get the right validator based on the declared $schema or default
|
|
@@ -484,7 +484,7 @@ class ComponentsObject(GenericObject):
|
|
|
484
484
|
f"Invalid type for '{field_name}': expected dict, got {type(value)}"
|
|
485
485
|
)
|
|
486
486
|
|
|
487
|
-
for key in value
|
|
487
|
+
for key in value:
|
|
488
488
|
if not re.match(pattern, key):
|
|
489
489
|
raise ValueError(
|
|
490
490
|
f"Invalid key '{key}' in '{field_name}': must match pattern {pattern}" # noqa: E501
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: amati
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Validates that a .yaml or .json file conforms to the OpenAPI Specifications 3.x.
|
|
5
5
|
Project-URL: Homepage, https://github.com/gwyli/amati
|
|
6
6
|
Project-URL: Issues, https://github.com/gwyli/amati/issues
|
|
7
7
|
Author-email: Ben <2551337+ben-alexander@users.noreply.github.com>
|
|
8
8
|
License-File: LICENSE
|
|
9
|
+
Keywords: json,openapi,openapi3,openapi3.0,openapi3.1,swagger,validation,validator,yaml
|
|
9
10
|
Classifier: Development Status :: 3 - Alpha
|
|
10
11
|
Classifier: Intended Audience :: Developers
|
|
11
12
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -2,22 +2,22 @@ amati/__init__.py,sha256=IXbWlVtFGTIdvxaafs8Qy8zeD3KjTDgK0omllFq8Jio,461
|
|
|
2
2
|
amati/_error_handler.py,sha256=_zs0hWqNf6NlXPk9-2MWyk6t5QGttDxNqatZ5YnCm6U,1245
|
|
3
3
|
amati/_logging.py,sha256=1q5mPlnZDSgAHl56lB20ZN6kV6OS-ew-8fvPeXF0uKI,1357
|
|
4
4
|
amati/_resolve_forward_references.py,sha256=-9MORpUhgusGJdvnH502p8-dc9Q6zqaB5XkPZvp4o7E,6509
|
|
5
|
-
amati/amati.py,sha256=
|
|
5
|
+
amati/amati.py,sha256=tziCq9lSEwMB2ILqeJKh1d84bs4GtiVYl3J277fEnYg,8187
|
|
6
6
|
amati/exceptions.py,sha256=MUzW7FsE0_4BJC99hStokMItKk7OvNBiqO6Zr6d_8cY,577
|
|
7
|
-
amati/file_handler.py,sha256=
|
|
8
|
-
amati/model_validators.py,sha256=
|
|
7
|
+
amati/file_handler.py,sha256=21Vx6pLZIL3BHN2ZDcrF7rFTfOkbXSC-ZM8WXaNVo7Q,8063
|
|
8
|
+
amati/model_validators.py,sha256=2Xxf9eNSe6873hoedctnLrsOqpDI65chAhyTIvA5Ui8,14820
|
|
9
9
|
amati/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
amati/_data/http_status_code.py,sha256=-BRAsm-EHOmvdKu0vHRWRPqYJu8pYUZ0bu9I4PyvYw4,867
|
|
11
11
|
amati/_data/iso9110.py,sha256=4NXWgAJYUrHW4USScOomt5LrilJ4pERI1EZrPjcFneo,569
|
|
12
|
-
amati/_data/media_types.py,sha256=
|
|
13
|
-
amati/_data/refresh.py,sha256=
|
|
12
|
+
amati/_data/media_types.py,sha256=eDSRU8iUmXQ1AHGSVVGfj2zeQ3-oA79bjgXeU5_PmME,1491
|
|
13
|
+
amati/_data/refresh.py,sha256=4xoV0bJaNxlbYTgPO_N9SGqE5tR51esCB_edFWUBCNM,4998
|
|
14
14
|
amati/_data/schemes.py,sha256=LLYqyw5iGG3xAGru11bKpQaKjm_DQl5fkT8t7rpwLh8,553
|
|
15
15
|
amati/_data/spdx_licences.py,sha256=AxzLH4qt4QCODLXZ4G54L2L5AYR58iU7wViap0S2m90,628
|
|
16
16
|
amati/_data/tlds.py,sha256=jDqcmmd9VKJZuk-PoLpU_xzjsKv5rFEKVQpJFiOVlR8,652
|
|
17
17
|
amati/_data/files/http-status-codes.json,sha256=AueWBemPsc6zRs7cDpB8ilCHR5qnkw0DIJjHZIGiJqk,11938
|
|
18
18
|
amati/_data/files/iso9110.json,sha256=UxJPL51KT_VT3S3TzdfFdgB4GxfE41CFehwBbWuYYlE,1946
|
|
19
|
-
amati/_data/files/media-types.json,sha256=
|
|
20
|
-
amati/_data/files/schemes.json,sha256=
|
|
19
|
+
amati/_data/files/media-types.json,sha256=ErLfyppEUgpgi7i3D96Iinkv4zbW6GWDkM-WKlhEUqg,56788
|
|
20
|
+
amati/_data/files/schemes.json,sha256=60O41WFwzYzsE8dWGglHFkiYARrqamvj09jUQoeQy7I,11248
|
|
21
21
|
amati/_data/files/spdx-licences.json,sha256=51c26uPzgWRAMh1_HF8kwmzjdCp5omnQedV5wTADNOU,285687
|
|
22
22
|
amati/_data/files/tlds.json,sha256=reuo17MSM9QfShj_esErUEDXRhUA-RY8sOk4OewsXCs,22433
|
|
23
23
|
amati/fields/__init__.py,sha256=dv5xKYZ-i9ARt9mg72vIjiu8DwgboqiWM4WL5AFxD8c,552
|
|
@@ -30,16 +30,16 @@ amati/fields/json.py,sha256=TsNMW5gcCc3tpjDd0Sew_8okzDQu6S_FLKjGGvoRVos,304
|
|
|
30
30
|
amati/fields/media.py,sha256=P5CILzL_MZN5huo9SVN6JguIDT7cXVIYlID_tuNk0VY,3049
|
|
31
31
|
amati/fields/oas.py,sha256=oRvruhRmY9VQtlqiPaRvGKeeOgjYE-JG5aUZYZay6Kg,1733
|
|
32
32
|
amati/fields/spdx_licences.py,sha256=lkmF4pRVMPjFAt-j7-pwbivhY8Ydhgo25f5AhQaLlis,2648
|
|
33
|
-
amati/fields/uri.py,sha256=
|
|
34
|
-
amati/grammars/oas.py,sha256=
|
|
33
|
+
amati/fields/uri.py,sha256=NLKYUoW4Fl3TaaBuhMuaEjYhxT91atWMQoVSYf9a-1I,12364
|
|
34
|
+
amati/grammars/oas.py,sha256=bZ84rwK-J1xaKjkeM8Z47VzhonhODGf-Cga1J6HdSUs,1678
|
|
35
35
|
amati/grammars/rfc6901.py,sha256=vQPk-JROikiB6Qzujs9EDszYbpRggc5EA1vkkGNJ36U,642
|
|
36
36
|
amati/grammars/rfc7159.py,sha256=ZYPGKh7zpcrZO7FA8pysUJ4jav2yq4WxFyi7r2GbjDY,2204
|
|
37
37
|
amati/validators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
|
-
amati/validators/generic.py,sha256=
|
|
39
|
-
amati/validators/oas304.py,sha256=
|
|
40
|
-
amati/validators/oas311.py,sha256=
|
|
41
|
-
amati-0.3.
|
|
42
|
-
amati-0.3.
|
|
43
|
-
amati-0.3.
|
|
44
|
-
amati-0.3.
|
|
45
|
-
amati-0.3.
|
|
38
|
+
amati/validators/generic.py,sha256=FawfxWyj3eXOCJuoycoN3o7G8PKrqje5zMwLbSmA6yk,5186
|
|
39
|
+
amati/validators/oas304.py,sha256=oGDzwG7OS9P-aXHDCyxcEIoQDoCPQjBMg0jPKtZvqr0,31970
|
|
40
|
+
amati/validators/oas311.py,sha256=NK-4P8Z4-HWxjt8PG0Vs9A9t4F2uPC3K4D8-sqJezIM,17315
|
|
41
|
+
amati-0.3.4.dist-info/METADATA,sha256=0t5RdxmH7uaDYrIGl5on9tJDLta4hRPJ7yX_1jhWqYw,7006
|
|
42
|
+
amati-0.3.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
43
|
+
amati-0.3.4.dist-info/entry_points.txt,sha256=sacBb6g0f0ZJtNjNYx93_Xe4y5xzawvklCFVXup9ru0,37
|
|
44
|
+
amati-0.3.4.dist-info/licenses/LICENSE,sha256=WAA01ZXeNs1bwpNWKR6aVucjtYjYm_iQIUYkCAENjqM,1070
|
|
45
|
+
amati-0.3.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|