clarifai 10.10.1__py3-none-any.whl → 10.11.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.
- clarifai/__init__.py +1 -1
- clarifai/cli/model.py +7 -2
- clarifai/client/model.py +1 -1
- clarifai/datasets/export/inputs_annotations.py +8 -0
- clarifai/runners/models/base_typed_model.py +6 -3
- clarifai/runners/models/model_run_locally.py +24 -9
- clarifai/runners/models/model_upload.py +1 -1
- clarifai/runners/utils/url_fetcher.py +19 -12
- {clarifai-10.10.1.dist-info → clarifai-10.11.0.dist-info}/METADATA +16 -16
- {clarifai-10.10.1.dist-info → clarifai-10.11.0.dist-info}/RECORD +14 -14
- {clarifai-10.10.1.dist-info → clarifai-10.11.0.dist-info}/WHEEL +1 -1
- {clarifai-10.10.1.dist-info → clarifai-10.11.0.dist-info}/LICENSE +0 -0
- {clarifai-10.10.1.dist-info → clarifai-10.11.0.dist-info}/entry_points.txt +0 -0
- {clarifai-10.10.1.dist-info → clarifai-10.11.0.dist-info}/top_level.txt +0 -0
clarifai/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "10.
|
1
|
+
__version__ = "10.11.0"
|
clarifai/cli/model.py
CHANGED
@@ -39,11 +39,16 @@ def upload(model_path, download_checkpoints, skip_dockerfile):
|
|
39
39
|
type=click.Path(exists=True),
|
40
40
|
required=True,
|
41
41
|
help='Path to the model directory.')
|
42
|
-
|
42
|
+
@click.option(
|
43
|
+
'--keep_env',
|
44
|
+
is_flag=True,
|
45
|
+
help='Flag to keep the virtual environment after testing the model\
|
46
|
+
locally. Defaults to False, which will delete the virtual environment after testing.')
|
47
|
+
def test_locally(model_path, keep_env=False):
|
43
48
|
"""Test model locally."""
|
44
49
|
try:
|
45
50
|
from clarifai.runners.models import model_run_locally
|
46
|
-
model_run_locally.main(model_path)
|
51
|
+
model_run_locally.main(model_path, keep_env=keep_env)
|
47
52
|
click.echo(f"Model tested locally from {model_path}.")
|
48
53
|
except Exception as e:
|
49
54
|
click.echo(f"Failed to test model locally: {e}", err=True)
|
clarifai/client/model.py
CHANGED
@@ -165,6 +165,14 @@ class InputAnnotationDownloader:
|
|
165
165
|
def _save_annotation_to_archive(self, new_archive: zipfile.ZipFile, annot_data: List[Dict],
|
166
166
|
file_name: str) -> None:
|
167
167
|
"""Gets the annotation response bytestring (from requests) and append to zip file."""
|
168
|
+
# Fill zero values for missing bounding box keys
|
169
|
+
for annot in annot_data:
|
170
|
+
if annot.get('regionInfo') and annot['regionInfo'].get('boundingBox'):
|
171
|
+
bbox = annot['regionInfo']['boundingBox']
|
172
|
+
bbox.setdefault('topRow', 0)
|
173
|
+
bbox.setdefault('leftCol', 0)
|
174
|
+
bbox.setdefault('bottomRow', 0)
|
175
|
+
bbox.setdefault('rightCol', 0)
|
168
176
|
# Serialize the dictionary to a JSON string
|
169
177
|
json_str = json.dumps(annot_data)
|
170
178
|
# Convert the JSON string to bytes
|
@@ -24,7 +24,8 @@ class AnyAnyModel(ModelRunner):
|
|
24
24
|
list_input_dict = [
|
25
25
|
InputDataHandler.from_proto(input).to_python() for input in input_request.inputs
|
26
26
|
]
|
27
|
-
inference_params = json_format.MessageToDict(
|
27
|
+
inference_params = json_format.MessageToDict(
|
28
|
+
input_request.model.model_version.output_info.params)
|
28
29
|
|
29
30
|
return list_input_dict, inference_params
|
30
31
|
|
@@ -141,7 +142,8 @@ class VisualInputModel(AnyAnyModel):
|
|
141
142
|
list_input_dict = [
|
142
143
|
InputDataHandler.from_proto(input).image(format="np") for input in input_request.inputs
|
143
144
|
]
|
144
|
-
inference_params = json_format.MessageToDict(
|
145
|
+
inference_params = json_format.MessageToDict(
|
146
|
+
input_request.model.model_version.output_info.params)
|
145
147
|
|
146
148
|
return list_input_dict, inference_params
|
147
149
|
|
@@ -181,7 +183,8 @@ class TextInputModel(AnyAnyModel):
|
|
181
183
|
def parse_input_request(
|
182
184
|
self, input_request: service_pb2.PostModelOutputsRequest) -> Tuple[List[Dict], Dict]:
|
183
185
|
list_input_text = [InputDataHandler.from_proto(input).text for input in input_request.inputs]
|
184
|
-
inference_params = json_format.MessageToDict(
|
186
|
+
inference_params = json_format.MessageToDict(
|
187
|
+
input_request.model.model_version.output_info.params)
|
185
188
|
|
186
189
|
return list_input_text, inference_params
|
187
190
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import hashlib
|
1
2
|
import importlib.util
|
2
3
|
import inspect
|
3
4
|
import os
|
@@ -13,6 +14,7 @@ from clarifai_grpc.grpc.api.status import status_code_pb2, status_pb2
|
|
13
14
|
from clarifai_protocol import BaseRunner
|
14
15
|
|
15
16
|
from clarifai.runners.models.model_upload import ModelUploader
|
17
|
+
from clarifai.runners.utils.url_fetcher import ensure_urls_downloaded
|
16
18
|
from clarifai.utils.logging import logger
|
17
19
|
|
18
20
|
|
@@ -24,17 +26,26 @@ class ModelRunLocally:
|
|
24
26
|
|
25
27
|
def create_temp_venv(self):
|
26
28
|
"""Create a temporary virtual environment."""
|
27
|
-
|
28
|
-
|
29
|
+
with open(self.requirements_file, "r") as f:
|
30
|
+
requirements_hash = hashlib.md5(f.read().encode('utf-8')).hexdigest()
|
31
|
+
|
32
|
+
temp_dir = os.path.join(tempfile.gettempdir(), str(requirements_hash))
|
29
33
|
venv_dir = os.path.join(temp_dir, "venv")
|
30
|
-
|
34
|
+
|
35
|
+
if os.path.exists(temp_dir):
|
36
|
+
logger.info(f"Using previous virtual environment at {temp_dir}")
|
37
|
+
use_existing_venv = True
|
38
|
+
else:
|
39
|
+
logger.info("Creating temporary virtual environment...")
|
40
|
+
use_existing_venv = False
|
41
|
+
venv.create(venv_dir, with_pip=True)
|
42
|
+
logger.info(f"Created temporary virtual environment at {venv_dir}")
|
31
43
|
|
32
44
|
self.venv_dir = venv_dir
|
33
45
|
self.temp_dir = temp_dir
|
34
46
|
self.python_executable = os.path.join(venv_dir, "bin", "python")
|
35
47
|
|
36
|
-
|
37
|
-
return venv_dir, temp_dir
|
48
|
+
return use_existing_venv
|
38
49
|
|
39
50
|
def install_requirements(self):
|
40
51
|
"""Install the dependencies from requirements.txt and Clarifai."""
|
@@ -102,6 +113,8 @@ class ModelRunLocally:
|
|
102
113
|
"""Perform inference using the runner."""
|
103
114
|
request = self._build_request()
|
104
115
|
|
116
|
+
ensure_urls_downloaded(request)
|
117
|
+
|
105
118
|
try:
|
106
119
|
return runner.predict(request)
|
107
120
|
except Exception as e:
|
@@ -175,16 +188,18 @@ class ModelRunLocally:
|
|
175
188
|
shutil.rmtree(self.temp_dir)
|
176
189
|
|
177
190
|
|
178
|
-
def main(model_path, run_model_server=False):
|
191
|
+
def main(model_path, run_model_server=False, keep_env=False):
|
179
192
|
|
180
193
|
manager = ModelRunLocally(model_path)
|
181
|
-
manager.create_temp_venv()
|
194
|
+
use_existing_env = manager.create_temp_venv()
|
182
195
|
|
183
196
|
try:
|
184
|
-
|
197
|
+
if not use_existing_env:
|
198
|
+
manager.install_requirements()
|
185
199
|
if run_model_server:
|
186
200
|
manager.run_model_server()
|
187
201
|
else:
|
188
202
|
manager.test_model()
|
189
203
|
finally:
|
190
|
-
|
204
|
+
if not keep_env:
|
205
|
+
manager.clean_up()
|
@@ -126,7 +126,7 @@ class ModelUploader:
|
|
126
126
|
user_id = model.get('user_id')
|
127
127
|
app_id = model.get('app_id')
|
128
128
|
|
129
|
-
base = os.environ.get('CLARIFAI_API_BASE', 'https://api
|
129
|
+
base = os.environ.get('CLARIFAI_API_BASE', 'https://api.clarifai.com')
|
130
130
|
|
131
131
|
self._client = BaseClient(user_id=user_id, app_id=app_id, base=base)
|
132
132
|
|
@@ -6,25 +6,32 @@ from clarifai.utils.logging import logger
|
|
6
6
|
|
7
7
|
|
8
8
|
def download_input(input):
|
9
|
+
_download_input_data(input.data)
|
10
|
+
if input.data.parts:
|
11
|
+
for i in range(len(input.data.parts)):
|
12
|
+
_download_input_data(input.data.parts[i].data)
|
13
|
+
|
14
|
+
|
15
|
+
def _download_input_data(input_data):
|
9
16
|
"""
|
10
17
|
This function will download any urls that are not already bytes.
|
11
18
|
"""
|
12
|
-
if
|
19
|
+
if input_data.image.url and not input_data.image.base64:
|
13
20
|
# Download the image
|
14
|
-
with fsspec.open(
|
15
|
-
|
16
|
-
if
|
21
|
+
with fsspec.open(input_data.image.url, 'rb') as f:
|
22
|
+
input_data.image.base64 = f.read()
|
23
|
+
if input_data.video.url and not input_data.video.base64:
|
17
24
|
# Download the video
|
18
|
-
with fsspec.open(
|
19
|
-
|
20
|
-
if
|
25
|
+
with fsspec.open(input_data.video.url, 'rb') as f:
|
26
|
+
input_data.video.base64 = f.read()
|
27
|
+
if input_data.audio.url and not input_data.audio.base64:
|
21
28
|
# Download the audio
|
22
|
-
with fsspec.open(
|
23
|
-
|
24
|
-
if
|
29
|
+
with fsspec.open(input_data.audio.url, 'rb') as f:
|
30
|
+
input_data.audio.base64 = f.read()
|
31
|
+
if input_data.text.url and not input_data.text.raw:
|
25
32
|
# Download the text
|
26
|
-
with fsspec.open(
|
27
|
-
|
33
|
+
with fsspec.open(input_data.text.url, 'r') as f:
|
34
|
+
input_data.text.raw = f.read()
|
28
35
|
|
29
36
|
|
30
37
|
def ensure_urls_downloaded(request, max_threads=128):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: clarifai
|
3
|
-
Version: 10.
|
3
|
+
Version: 10.11.0
|
4
4
|
Summary: Clarifai Python SDK
|
5
5
|
Home-page: https://github.com/Clarifai/clarifai-python
|
6
6
|
Author: Clarifai
|
@@ -20,22 +20,22 @@ Classifier: Operating System :: OS Independent
|
|
20
20
|
Requires-Python: >=3.8
|
21
21
|
Description-Content-Type: text/markdown
|
22
22
|
License-File: LICENSE
|
23
|
-
Requires-Dist: clarifai-grpc
|
24
|
-
Requires-Dist: clarifai-protocol
|
25
|
-
Requires-Dist: numpy
|
26
|
-
Requires-Dist: tqdm
|
27
|
-
Requires-Dist: tritonclient
|
28
|
-
Requires-Dist: rich
|
29
|
-
Requires-Dist: PyYAML
|
30
|
-
Requires-Dist: schema
|
31
|
-
Requires-Dist: Pillow
|
32
|
-
Requires-Dist: inquirerpy
|
33
|
-
Requires-Dist: tabulate
|
34
|
-
Requires-Dist: protobuf
|
35
|
-
Requires-Dist: fsspec
|
36
|
-
Requires-Dist: click
|
23
|
+
Requires-Dist: clarifai-grpc>=10.10.2
|
24
|
+
Requires-Dist: clarifai-protocol>=0.0.6
|
25
|
+
Requires-Dist: numpy>=1.22.0
|
26
|
+
Requires-Dist: tqdm>=4.65.0
|
27
|
+
Requires-Dist: tritonclient>=2.34.0
|
28
|
+
Requires-Dist: rich>=13.4.2
|
29
|
+
Requires-Dist: PyYAML>=6.0.1
|
30
|
+
Requires-Dist: schema==0.7.5
|
31
|
+
Requires-Dist: Pillow>=9.5.0
|
32
|
+
Requires-Dist: inquirerpy==0.3.4
|
33
|
+
Requires-Dist: tabulate>=0.9.0
|
34
|
+
Requires-Dist: protobuf==5.27.3
|
35
|
+
Requires-Dist: fsspec==2024.6.1
|
36
|
+
Requires-Dist: click==8.1.7
|
37
37
|
Provides-Extra: all
|
38
|
-
Requires-Dist: pycocotools
|
38
|
+
Requires-Dist: pycocotools==2.0.6; extra == "all"
|
39
39
|
|
40
40
|
<h1 align="center">
|
41
41
|
<a href="https://www.clarifai.com/"><img alt="Clarifai" title="Clarifai" src="https://github.com/user-attachments/assets/623b883b-7fe5-4b95-bbfa-8691f5779af4"></a>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
clarifai/__init__.py,sha256=
|
1
|
+
clarifai/__init__.py,sha256=QlkUWf1vZWZO1B4-0PjOW339CFFq5tlWz3teIz9l6-E,24
|
2
2
|
clarifai/cli.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
clarifai/errors.py,sha256=RwzTajwds51wLD0MVlMC5kcpBnzRpreDLlazPSBZxrg,2605
|
4
4
|
clarifai/versions.py,sha256=jctnczzfGk_S3EnVqb2FjRKfSREkNmvNEwAAa_VoKiQ,222
|
@@ -7,7 +7,7 @@ clarifai/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
clarifai/cli/base.py,sha256=okuBNlMmLEQw9-0f4yzemCtneNNRTVXUugCwD58-ZtQ,3417
|
8
8
|
clarifai/cli/compute_cluster.py,sha256=N2dNQNJEPg9nxsb8x2igEzYuGRzjn7l4kNttjFIxmhI,1827
|
9
9
|
clarifai/cli/deployment.py,sha256=sUEuz5-rtozMx8deVcJXLi6lHsP2jc8x3y2MpUAVfqY,2506
|
10
|
-
clarifai/cli/model.py,sha256=
|
10
|
+
clarifai/cli/model.py,sha256=0DRp3TjySvRwyUnt-v1nqhYOcTnVtEZ0jdXH4TBtuQ8,2183
|
11
11
|
clarifai/cli/nodepool.py,sha256=yihxS_rIFoBBKzRlqBX8Ab42iPpBMJrJFsk8saph6ms,3049
|
12
12
|
clarifai/client/__init__.py,sha256=xI1U0l5AZdRThvQAXCLsd9axxyFzXXJ22m8LHqVjQRU,662
|
13
13
|
clarifai/client/app.py,sha256=6pckYme1urV2YJjLIYfeZ-vH0Z5YSQa51jzIMcEfwug,38342
|
@@ -17,7 +17,7 @@ clarifai/client/dataset.py,sha256=AIzwbYs-ExkmUqW9nuEJgpW8-D7rjA1PtopU5Iu6YZE,32
|
|
17
17
|
clarifai/client/deployment.py,sha256=w7Y6pA1rYG4KRK1SwusRZc2sQRXlG8wezuVdzSWpCo0,2586
|
18
18
|
clarifai/client/input.py,sha256=GvrPV2chThNjimekBIleuIr6AD10_wrfc-1Hm5C4NQ8,45648
|
19
19
|
clarifai/client/lister.py,sha256=03KGMvs5RVyYqxLsSrWhNc34I8kiF1Ph0NeyEwu7nMU,2082
|
20
|
-
clarifai/client/model.py,sha256=
|
20
|
+
clarifai/client/model.py,sha256=8koRWV_-cLLtZYFHQzNxMFw2X1VXAZ6aJI-1cOp6r4U,84655
|
21
21
|
clarifai/client/module.py,sha256=FTkm8s9m-EaTKN7g9MnLhGJ9eETUfKG7aWZ3o1RshYs,4204
|
22
22
|
clarifai/client/nodepool.py,sha256=la3vTFrO4LX8zm2eQ5jqf2L0-kQ63Dano8FibadoZbk,10152
|
23
23
|
clarifai/client/search.py,sha256=GaPWN6JmTQGZaCHr6U1yv0zqR6wKFl7i9IVLg2ul1CI,14254
|
@@ -36,7 +36,7 @@ clarifai/constants/search.py,sha256=yYEqTaFg-KdnpJE_Ytp-EPVHIIC395iNtZrpVlLIf4o,
|
|
36
36
|
clarifai/constants/workflow.py,sha256=cECq1xdvf44MCdtK2AbkiuuwhyL-6OWZdQfYbsLKy_o,33
|
37
37
|
clarifai/datasets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
38
|
clarifai/datasets/export/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
|
-
clarifai/datasets/export/inputs_annotations.py,sha256=
|
39
|
+
clarifai/datasets/export/inputs_annotations.py,sha256=3AtUBrMIjw8H3ehDsJFYcBFoAZ1QKQo1hXTMsHh8f20,10159
|
40
40
|
clarifai/datasets/upload/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
41
41
|
clarifai/datasets/upload/base.py,sha256=UIc0ufyIBCrb83_sFpv21L8FshsX4nwsLYQkdlJfzD4,2357
|
42
42
|
clarifai/datasets/upload/features.py,sha256=jv2x7jGZKS-LMt87sEZNBwwOskHbP26XTMjoiaSA5pg,2024
|
@@ -64,17 +64,17 @@ clarifai/runners/__init__.py,sha256=3vr4RVvN1IRy2SxJpyycAAvrUBbH-mXR7pqUmu4w36A,
|
|
64
64
|
clarifai/runners/server.py,sha256=CVLrv2DjzCvKVXcJ4SWvcFWUZq0bdlBmyEpfVlfgT2A,4902
|
65
65
|
clarifai/runners/dockerfile_template/Dockerfile.template,sha256=-T38Rscpjot8WVuUTUq1_N0xz_gg653FOHV4XQYGG-U,1453
|
66
66
|
clarifai/runners/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
67
|
-
clarifai/runners/models/base_typed_model.py,sha256=
|
67
|
+
clarifai/runners/models/base_typed_model.py,sha256=DWEUK5ge9NVZE6LkT3BNTFYjYMPHz-nDgPA48Y0DGXU,7859
|
68
68
|
clarifai/runners/models/model_class.py,sha256=9JSPAr4U4K7xI0kSl-q0mHB06zknm2OR-8XIgBCto94,1611
|
69
|
-
clarifai/runners/models/model_run_locally.py,sha256=
|
69
|
+
clarifai/runners/models/model_run_locally.py,sha256=6LgRzTTDjmGvAV6gEUhW3T3yoCMpLqkOUGa4anZUbig,7144
|
70
70
|
clarifai/runners/models/model_runner.py,sha256=3vzoastQxkGRDK8T9aojDsLNBb9A3IiKm6YmbFrE9S0,6241
|
71
71
|
clarifai/runners/models/model_servicer.py,sha256=X4715PVA5PBurRTYcwSEudg8fShGV6InAF4mmRlRcHg,2826
|
72
|
-
clarifai/runners/models/model_upload.py,sha256=
|
72
|
+
clarifai/runners/models/model_upload.py,sha256=N3KCAHibeTJdnlDx1vixYkV1vl6lI6GA8LL7TuvUax8,20430
|
73
73
|
clarifai/runners/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
74
74
|
clarifai/runners/utils/data_handler.py,sha256=sxy9zlAgI6ETuxCQhUgEXAn2GCsaW1GxpK6GTaMne0g,6966
|
75
75
|
clarifai/runners/utils/data_utils.py,sha256=R1iQ82TuQ9JwxCJk8yEB1Lyb0BYVhVbWJI9YDi1zGOs,318
|
76
76
|
clarifai/runners/utils/loader.py,sha256=1oktDUQA1Lpv0NiCXFwoxpp0jqqbvB7sWvpymwyWY2E,4243
|
77
|
-
clarifai/runners/utils/url_fetcher.py,sha256
|
77
|
+
clarifai/runners/utils/url_fetcher.py,sha256=v_8JOWmkyFAzsBulsieKX7Nfjy1Yg7wGSZeqfEvw2cg,1640
|
78
78
|
clarifai/schema/search.py,sha256=JjTi8ammJgZZ2OGl4K6tIA4zEJ1Fr2ASZARXavI1j5c,2448
|
79
79
|
clarifai/urls/helper.py,sha256=tjoMGGHuWX68DUB0pk4MEjrmFsClUAQj2jmVEM_Sy78,4751
|
80
80
|
clarifai/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -91,9 +91,9 @@ clarifai/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
|
|
91
91
|
clarifai/workflows/export.py,sha256=vICRhIreqDSShxLKjHNM2JwzKsf1B4fdXB0ciMcA70k,1945
|
92
92
|
clarifai/workflows/utils.py,sha256=nGeB_yjVgUO9kOeKTg4OBBaBz-AwXI3m-huSVj-9W18,1924
|
93
93
|
clarifai/workflows/validate.py,sha256=yJq03MaJqi5AK3alKGJJBR89xmmjAQ31sVufJUiOqY8,2556
|
94
|
-
clarifai-10.
|
95
|
-
clarifai-10.
|
96
|
-
clarifai-10.
|
97
|
-
clarifai-10.
|
98
|
-
clarifai-10.
|
99
|
-
clarifai-10.
|
94
|
+
clarifai-10.11.0.dist-info/LICENSE,sha256=mUqF_d12-qE2n41g7C5_sq-BMLOcj6CNN-jevr15YHU,555
|
95
|
+
clarifai-10.11.0.dist-info/METADATA,sha256=C1A5Myx1yQUdZRhpNDzOV-zm6a7OfBVbSireNn1e7mY,19550
|
96
|
+
clarifai-10.11.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
97
|
+
clarifai-10.11.0.dist-info/entry_points.txt,sha256=X9FZ4Z-i_r2Ud1RpZ9sNIFYuu_-9fogzCMCRUD9hyX0,51
|
98
|
+
clarifai-10.11.0.dist-info/top_level.txt,sha256=wUMdCQGjkxaynZ6nZ9FAnvBUCgp5RJUVFSy2j-KYo0s,9
|
99
|
+
clarifai-10.11.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|