clarifai 11.0.5__py3-none-any.whl → 11.0.6__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 CHANGED
@@ -1 +1 @@
1
- __version__ = "11.0.5"
1
+ __version__ = "11.0.6"
@@ -2,6 +2,7 @@ import hashlib
2
2
  import importlib.util
3
3
  import inspect
4
4
  import os
5
+ import platform
5
6
  import shutil
6
7
  import signal
7
8
  import subprocess
@@ -27,7 +28,7 @@ class ModelRunLocally:
27
28
  self.requirements_file = os.path.join(self.model_path, "requirements.txt")
28
29
 
29
30
  # ModelUploader contains multiple useful methods to interact with the model
30
- self.uploader = ModelUploader(self.model_path)
31
+ self.uploader = ModelUploader(self.model_path, download_validation_only=True)
31
32
  self.config = self.uploader.config
32
33
 
33
34
  def _requirements_hash(self):
@@ -35,6 +36,23 @@ class ModelRunLocally:
35
36
  with open(self.requirements_file, "r") as f:
36
37
  return hashlib.md5(f.read().encode('utf-8')).hexdigest()
37
38
 
39
+ def _get_env_executable(self):
40
+ """Get the python executable from the virtual environment."""
41
+ # Depending on the platform, venv scripts are placed in either "Scripts" (Windows) or "bin" (Linux/Mac)
42
+ if platform.system().lower().startswith("win"):
43
+ scripts_folder = "Scripts"
44
+ python_exe = "python.exe"
45
+ pip_exe = "pip.exe"
46
+ else:
47
+ scripts_folder = "bin"
48
+ python_exe = "python"
49
+ pip_exe = "pip"
50
+
51
+ self.python_executable = os.path.join(self.venv_dir, scripts_folder, python_exe)
52
+ self.pip_executable = os.path.join(self.venv_dir, scripts_folder, pip_exe)
53
+
54
+ return self.python_executable, self.pip_executable
55
+
38
56
  def create_temp_venv(self):
39
57
  """Create a temporary virtual environment."""
40
58
  requirements_hash = self._requirements_hash()
@@ -53,13 +71,13 @@ class ModelRunLocally:
53
71
 
54
72
  self.venv_dir = venv_dir
55
73
  self.temp_dir = temp_dir
56
- self.python_executable = os.path.join(venv_dir, "bin", "python")
74
+ self.python_executable, self.pip_executable = self._get_env_executable()
57
75
 
58
76
  return use_existing_venv
59
77
 
60
78
  def install_requirements(self):
61
79
  """Install the dependencies from requirements.txt and Clarifai."""
62
- pip_executable = os.path.join(self.venv_dir, "bin", "pip")
80
+ _, pip_executable = self._get_env_executable()
63
81
  try:
64
82
  logger.info(
65
83
  f"Installing requirements from {self.requirements_file}... in the virtual environment {self.venv_dir}"
@@ -104,8 +122,7 @@ class ModelRunLocally:
104
122
  def _build_request(self):
105
123
  """Create a mock inference request for testing the model."""
106
124
 
107
- uploader = ModelUploader(self.model_path)
108
- model_version_proto = uploader.get_model_version_proto()
125
+ model_version_proto = self.uploader.get_model_version_proto()
109
126
  model_version_proto.id = "model_version"
110
127
 
111
128
  return service_pb2.PostModelOutputsRequest(
@@ -213,12 +230,16 @@ class ModelRunLocally:
213
230
 
214
231
  def test_model(self):
215
232
  """Test the model by running it locally in the virtual environment."""
216
- command = [
217
- self.python_executable,
218
- "-c",
219
- f"import sys; sys.path.append('{os.path.dirname(os.path.abspath(__file__))}'); "
220
- f"from model_run_locally import ModelRunLocally; ModelRunLocally('{self.model_path}')._run_test()",
221
- ]
233
+
234
+ import_path = repr(os.path.dirname(os.path.abspath(__file__)))
235
+ model_path = repr(self.model_path)
236
+
237
+ command_string = (f"import sys; "
238
+ f"sys.path.append({import_path}); "
239
+ f"from model_run_locally import ModelRunLocally; "
240
+ f"ModelRunLocally({model_path})._run_test()")
241
+
242
+ command = [self.python_executable, "-c", command_string]
222
243
  process = None
223
244
  try:
224
245
  logger.info("Testing the model locally...")
@@ -335,6 +356,12 @@ class ModelRunLocally:
335
356
  logger.info(f"Docker image '{image_name}' does not exist!")
336
357
  return False
337
358
 
359
+ def _gpu_is_available(self):
360
+ """
361
+ Checks if nvidia-smi is available, indicating a GPU is likely accessible.
362
+ """
363
+ return shutil.which("nvidia-smi") is not None
364
+
338
365
  def run_docker_container(self,
339
366
  image_name,
340
367
  container_name="clarifai-model-container",
@@ -344,9 +371,9 @@ class ModelRunLocally:
344
371
  try:
345
372
  logger.info(f"Running Docker container '{container_name}' from image '{image_name}'...")
346
373
  # Base docker run command
347
- cmd = [
348
- "docker", "run", "--name", container_name, '--rm', "--gpus", "all", "--network", "host"
349
- ]
374
+ cmd = ["docker", "run", "--name", container_name, '--rm', "--network", "host"]
375
+ if self._gpu_is_available():
376
+ cmd.extend(["--gpus", "all"])
350
377
  # Add volume mappings
351
378
  cmd.extend(["-v", f"{self.model_path}:/app/model_dir/main"])
352
379
  # Add environment variables
@@ -393,9 +420,9 @@ class ModelRunLocally:
393
420
  try:
394
421
  logger.info("Testing the model inside the Docker container...")
395
422
  # Base docker run command
396
- cmd = [
397
- "docker", "run", "--name", container_name, '--rm', "--gpus", "all", "--network", "host"
398
- ]
423
+ cmd = ["docker", "run", "--name", container_name, '--rm', "--network", "host"]
424
+ if self._gpu_is_available():
425
+ cmd.extend(["--gpus", "all"])
399
426
  # update the entrypoint for testing the model
400
427
  cmd.extend(["--entrypoint", "python"])
401
428
  # Add volume mappings
@@ -502,7 +529,10 @@ def main(model_path,
502
529
  if not manager.docker_image_exists(image_name):
503
530
  manager.build_docker_image(image_name=image_name)
504
531
  try:
505
- envs = {'CLARIFAI_PAT': os.environ['CLARIFAI_PAT'], 'CLARIFAI_USER_ID': 'n/a'}
532
+ envs = {
533
+ 'CLARIFAI_PAT': os.environ['CLARIFAI_PAT'],
534
+ 'CLARIFAI_API_BASE': os.environ.get('CLARIFAI_API_BASE', 'https://api.clarifai.com')
535
+ }
506
536
  if run_model_server:
507
537
  manager.run_docker_container(
508
538
  image_name=image_name, container_name=container_name, port=port, env_vars=envs)
@@ -1,6 +1,7 @@
1
1
  import os
2
2
  import re
3
3
  import sys
4
+ import tarfile
4
5
  import time
5
6
  from string import Template
6
7
 
@@ -54,7 +55,7 @@ class ModelUploader:
54
55
  def _validate_folder(self, folder):
55
56
  if folder == ".":
56
57
  folder = "" # will getcwd() next which ends with /
57
- if not folder.startswith("/"):
58
+ if not os.path.isabs(folder):
58
59
  folder = os.path.join(os.getcwd(), folder)
59
60
  logger.info(f"Validating folder: {folder}")
60
61
  if not os.path.exists(folder):
@@ -428,14 +429,15 @@ class ModelUploader:
428
429
 
429
430
  model_version_proto = self.get_model_version_proto()
430
431
 
431
- if download_checkpoints:
432
- tar_cmd = f"tar --exclude=*~ --exclude={self.tar_file} -czvf {self.tar_file} -C {self.folder} ."
433
- else: # we don't want to send the checkpoints up even if they are in the folder.
434
- logger.info(f"Skipping {self.checkpoint_path} in the tar file that is uploaded.")
435
- tar_cmd = f"tar --exclude={self.checkpoint_suffix} --exclude=*~ --exclude={self.tar_file} -czvf {self.tar_file} -C {self.folder} ."
436
- # Tar the folder
437
- logger.debug(tar_cmd)
438
- os.system(tar_cmd)
432
+ def filter_func(tarinfo):
433
+ name = tarinfo.name
434
+ exclude = [self.tar_file, "*~"]
435
+ if not download_checkpoints:
436
+ exclude.append(self.checkpoint_suffix)
437
+ return None if any(name.endswith(ex) for ex in exclude) else tarinfo
438
+
439
+ with tarfile.open(self.tar_file, "w:gz") as tar:
440
+ tar.add(self.folder, arcname=".", filter=filter_func)
439
441
  logger.info("Tarring complete, about to start upload.")
440
442
 
441
443
  file_size = os.path.getsize(self.tar_file)
@@ -467,9 +469,9 @@ class ModelUploader:
467
469
  self.model_version_id = response.model_version_id
468
470
  logger.info(f"Created Model Version ID: {self.model_version_id}")
469
471
  logger.info(f"Full url to that version is: {self.model_url}")
470
-
471
- success = self.monitor_model_build()
472
- if success: # cleanup the tar_file if it exists
472
+ try:
473
+ self.monitor_model_build()
474
+ finally:
473
475
  if os.path.exists(self.tar_file):
474
476
  logger.info(f"Cleaning up upload file: {self.tar_file}")
475
477
  os.remove(self.tar_file)
@@ -6,27 +6,17 @@ PYTHON_BASE_IMAGE = registry + '/python-base:{python_version}'
6
6
  TORCH_BASE_IMAGE = registry + '/torch:{torch_version}-py{python_version}-cuda{cuda_version}'
7
7
 
8
8
  # List of available python base images
9
- AVAILABLE_PYTHON_IMAGES = ['3.11', '3.12', '3.13']
9
+ AVAILABLE_PYTHON_IMAGES = ['3.11', '3.12']
10
10
 
11
11
  DEFAULT_PYTHON_VERSION = 3.12
12
12
 
13
13
  # List of available torch images
14
14
  AVAILABLE_TORCH_IMAGES = [
15
- '2.2.2-py3.11-cuda121',
16
- '2.3.1-py3.11-cuda121',
17
- '2.4.0-py3.11-cuda121',
18
15
  '2.4.0-py3.11-cuda124',
19
- '2.4.1-py3.11-cuda121',
20
16
  '2.4.1-py3.11-cuda124',
21
- '2.5.1-py3.11-cuda121',
22
17
  '2.5.1-py3.11-cuda124',
23
- '2.2.2-py3.12-cuda121',
24
- '2.3.1-py3.12-cuda121',
25
- '2.4.0-py3.12-cuda121',
26
18
  '2.4.0-py3.12-cuda124',
27
- '2.4.1-py3.12-cuda121',
28
19
  '2.4.1-py3.12-cuda124',
29
- '2.5.1-py3.12-cuda121',
30
20
  '2.5.1-py3.12-cuda124',
31
21
  # '2.2.2-py3.13-cuda121',
32
22
  # '2.3.1-py3.13-cuda121',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: clarifai
3
- Version: 11.0.5
3
+ Version: 11.0.6
4
4
  Summary: Clarifai Python SDK
5
5
  Home-page: https://github.com/Clarifai/clarifai-python
6
6
  Author: Clarifai
@@ -20,16 +20,14 @@ 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>=11.0.0
23
+ Requires-Dist: clarifai-grpc>=11.0.4
24
24
  Requires-Dist: clarifai-protocol>=0.0.14
25
25
  Requires-Dist: numpy>=1.22.0
26
26
  Requires-Dist: tqdm>=4.65.0
27
- Requires-Dist: tritonclient>=2.34.0
28
27
  Requires-Dist: rich>=13.4.2
29
28
  Requires-Dist: PyYAML>=6.0.1
30
29
  Requires-Dist: schema==0.7.5
31
30
  Requires-Dist: Pillow>=9.5.0
32
- Requires-Dist: inquirerpy==0.3.4
33
31
  Requires-Dist: tabulate>=0.9.0
34
32
  Requires-Dist: fsspec==2024.6.1
35
33
  Requires-Dist: click==8.1.7
@@ -1,4 +1,4 @@
1
- clarifai/__init__.py,sha256=p5EKOiD3MZA1O2ik4FV32rDBe9Z8ERMDwHJDG9GNB-k,23
1
+ clarifai/__init__.py,sha256=nQygEIhjCD5SokxF73HP_3i7Niq5x0WTTxfAoGlt5Sw,23
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
@@ -66,12 +66,12 @@ clarifai/runners/dockerfile_template/Dockerfile.template,sha256=mW3Bdu9elMpI75Ub
66
66
  clarifai/runners/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
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=OhzQbmaV8Wwgs2H0KhdDF6Z7bYSaIh4RRA0QwSiv5vY,20644
69
+ clarifai/runners/models/model_run_locally.py,sha256=Jo43XmhmnypvLQ9dm5AWcjjoBb2-ohKPpPl4R-e7rDE,21788
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=Mxms6hg_u62p_WvuoTUOJ5QFNugWkmt7vnrk5dJnqg8,23927
72
+ clarifai/runners/models/model_upload.py,sha256=JFyRirAARTXLh2gvGQwOz9IxxNtJwMnv4tzLmrGODxc,23752
73
73
  clarifai/runners/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
- clarifai/runners/utils/const.py,sha256=eyBrj5ywuGKPF-IFipm7yjiYyLhnsKhMNZ6xF-OvykQ,1250
74
+ clarifai/runners/utils/const.py,sha256=ass3U8UUqyGVE0KJFgw6Zd5bZb-Bc3b0LqSwSF0QIX4,962
75
75
  clarifai/runners/utils/data_handler.py,sha256=sxy9zlAgI6ETuxCQhUgEXAn2GCsaW1GxpK6GTaMne0g,6966
76
76
  clarifai/runners/utils/data_utils.py,sha256=R1iQ82TuQ9JwxCJk8yEB1Lyb0BYVhVbWJI9YDi1zGOs,318
77
77
  clarifai/runners/utils/loader.py,sha256=Q4psyvHjGPDHA6GMFLEhSSVqPRVq4vJyYyDItKn1WwU,6100
@@ -92,9 +92,9 @@ clarifai/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
92
92
  clarifai/workflows/export.py,sha256=vICRhIreqDSShxLKjHNM2JwzKsf1B4fdXB0ciMcA70k,1945
93
93
  clarifai/workflows/utils.py,sha256=nGeB_yjVgUO9kOeKTg4OBBaBz-AwXI3m-huSVj-9W18,1924
94
94
  clarifai/workflows/validate.py,sha256=yJq03MaJqi5AK3alKGJJBR89xmmjAQ31sVufJUiOqY8,2556
95
- clarifai-11.0.5.dist-info/LICENSE,sha256=mUqF_d12-qE2n41g7C5_sq-BMLOcj6CNN-jevr15YHU,555
96
- clarifai-11.0.5.dist-info/METADATA,sha256=SDCVegVMwwCs-h_cv6WgK5LBfWoNmjsKLWH8uRrs2q8,22456
97
- clarifai-11.0.5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
98
- clarifai-11.0.5.dist-info/entry_points.txt,sha256=X9FZ4Z-i_r2Ud1RpZ9sNIFYuu_-9fogzCMCRUD9hyX0,51
99
- clarifai-11.0.5.dist-info/top_level.txt,sha256=wUMdCQGjkxaynZ6nZ9FAnvBUCgp5RJUVFSy2j-KYo0s,9
100
- clarifai-11.0.5.dist-info/RECORD,,
95
+ clarifai-11.0.6.dist-info/LICENSE,sha256=mUqF_d12-qE2n41g7C5_sq-BMLOcj6CNN-jevr15YHU,555
96
+ clarifai-11.0.6.dist-info/METADATA,sha256=qwxANSfX3ww_GHa4iPPnz6Fu9q5Mn7Hw8oNKoFUEj5o,22387
97
+ clarifai-11.0.6.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
98
+ clarifai-11.0.6.dist-info/entry_points.txt,sha256=X9FZ4Z-i_r2Ud1RpZ9sNIFYuu_-9fogzCMCRUD9hyX0,51
99
+ clarifai-11.0.6.dist-info/top_level.txt,sha256=wUMdCQGjkxaynZ6nZ9FAnvBUCgp5RJUVFSy2j-KYo0s,9
100
+ clarifai-11.0.6.dist-info/RECORD,,