clarifai 11.6.0__tar.gz → 11.6.2__tar.gz
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-11.6.0/clarifai.egg-info → clarifai-11.6.2}/PKG-INFO +2 -2
- clarifai-11.6.2/clarifai/__init__.py +1 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/base.py +2 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/model.py +138 -61
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/pipeline_step.py +1 -1
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/model.py +14 -5
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/utils/code_script.py +5 -2
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/utils/constants.py +4 -2
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/utils/misc.py +63 -1
- {clarifai-11.6.0 → clarifai-11.6.2/clarifai.egg-info}/PKG-INFO +2 -2
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai.egg-info/requires.txt +1 -1
- {clarifai-11.6.0 → clarifai-11.6.2}/requirements.txt +1 -1
- clarifai-11.6.0/clarifai/__init__.py +0 -1
- {clarifai-11.6.0 → clarifai-11.6.2}/LICENSE +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/MANIFEST.in +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/README.md +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/README.md +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/__main__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/compute_cluster.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/deployment.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/nodepool.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/pipeline.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/templates/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/templates/model_templates.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/templates/pipeline_step_templates.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli/templates/pipeline_templates.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/cli.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/app.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/auth/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/auth/helper.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/auth/register.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/auth/stub.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/base.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/compute_cluster.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/dataset.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/deployment.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/input.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/lister.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/model_client.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/module.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/nodepool.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/pipeline.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/runner.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/search.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/user.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/client/workflow.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/constants/base.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/constants/dataset.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/constants/input.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/constants/model.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/constants/rag.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/constants/search.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/constants/workflow.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/export/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/export/inputs_annotations.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/base.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/features.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/image.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/loaders/README.md +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/loaders/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/loaders/coco_captions.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/loaders/coco_detection.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/loaders/imagenet_classification.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/loaders/xview_detection.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/multimodal.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/text.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/utils.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/errors.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/models/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/models/api.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/modules/README.md +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/modules/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/modules/css.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/modules/pages.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/modules/style.css +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/rag/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/rag/rag.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/rag/utils.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/dockerfile_template/Dockerfile.template +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/models/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/models/dummy_openai_model.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/models/mcp_class.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/models/model_builder.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/models/model_class.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/models/model_run_locally.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/models/model_runner.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/models/model_servicer.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/models/openai_class.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/models/visual_classifier_class.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/models/visual_detector_class.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/pipeline_steps/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/pipeline_steps/pipeline_step_builder.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/pipelines/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/pipelines/pipeline_builder.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/server.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/utils/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/utils/const.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/utils/data_types/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/utils/data_types/data_types.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/utils/data_utils.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/utils/loader.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/utils/method_signatures.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/utils/model_utils.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/utils/openai_convertor.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/utils/pipeline_validation.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/utils/serializers.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/utils/url_fetcher.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/schema/search.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/urls/helper.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/utils/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/utils/cli.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/utils/config.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/utils/evaluation/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/utils/evaluation/helpers.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/utils/evaluation/main.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/utils/evaluation/testset_annotation_parser.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/utils/logging.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/utils/model_train.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/utils/protobuf.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/versions.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/workflows/__init__.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/workflows/export.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/workflows/utils.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai/workflows/validate.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai.egg-info/SOURCES.txt +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai.egg-info/dependency_links.txt +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai.egg-info/entry_points.txt +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/clarifai.egg-info/top_level.txt +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/pyproject.toml +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/setup.cfg +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/setup.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_app.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_async_stub.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_auth.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_data_upload.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_eval.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_list_models.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_misc.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_model_predict.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_model_train.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_modules.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_pipeline_client.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_rag.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_search.py +0 -0
- {clarifai-11.6.0 → clarifai-11.6.2}/tests/test_stub.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: clarifai
|
3
|
-
Version: 11.6.
|
3
|
+
Version: 11.6.2
|
4
4
|
Home-page: https://github.com/Clarifai/clarifai-python
|
5
5
|
Author: Clarifai
|
6
6
|
Author-email: support@clarifai.com
|
@@ -19,7 +19,7 @@ Classifier: Operating System :: OS Independent
|
|
19
19
|
Requires-Python: >=3.8
|
20
20
|
Description-Content-Type: text/markdown
|
21
21
|
License-File: LICENSE
|
22
|
-
Requires-Dist: clarifai-grpc>=11.
|
22
|
+
Requires-Dist: clarifai-grpc>=11.6.0
|
23
23
|
Requires-Dist: clarifai-protocol>=0.0.25
|
24
24
|
Requires-Dist: numpy>=1.22.0
|
25
25
|
Requires-Dist: tqdm>=4.65.0
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "11.6.2"
|
@@ -6,6 +6,7 @@ import sys
|
|
6
6
|
import click
|
7
7
|
import yaml
|
8
8
|
|
9
|
+
from clarifai import __version__
|
9
10
|
from clarifai.utils.cli import AliasedGroup, TableFormatter, load_command_modules
|
10
11
|
from clarifai.utils.config import Config, Context
|
11
12
|
from clarifai.utils.constants import DEFAULT_BASE, DEFAULT_CONFIG, DEFAULT_UI
|
@@ -14,6 +15,7 @@ from clarifai.utils.logging import logger
|
|
14
15
|
|
15
16
|
# @click.group(cls=CustomMultiGroup)
|
16
17
|
@click.group(cls=AliasedGroup)
|
18
|
+
@click.version_option(version=__version__)
|
17
19
|
@click.option('--config', default=DEFAULT_CONFIG)
|
18
20
|
@click.pass_context
|
19
21
|
def cli(ctx, config):
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import os
|
2
2
|
import shutil
|
3
|
+
import tempfile
|
3
4
|
|
4
5
|
import click
|
5
6
|
|
@@ -16,13 +17,19 @@ from clarifai.utils.constants import (
|
|
16
17
|
DEFAULT_LOCAL_DEV_NODEPOOL_ID,
|
17
18
|
)
|
18
19
|
from clarifai.utils.logging import logger
|
20
|
+
from clarifai.utils.misc import (
|
21
|
+
clone_github_repo,
|
22
|
+
format_github_repo_url,
|
23
|
+
)
|
19
24
|
|
20
25
|
|
21
26
|
@cli.group(
|
22
27
|
['model'], context_settings={'max_content_width': shutil.get_terminal_size().columns - 10}
|
23
28
|
)
|
24
29
|
def model():
|
25
|
-
"""Manage
|
30
|
+
"""Manage & Develop Models: init, download-checkpoints, signatures, upload\n
|
31
|
+
Run & Test Models Locally: local-runner, local-grpc, local-test\n
|
32
|
+
Model Inference: list, predict"""
|
26
33
|
|
27
34
|
|
28
35
|
@model.command()
|
@@ -38,7 +45,22 @@ def model():
|
|
38
45
|
required=False,
|
39
46
|
help='Model type: "mcp" for MCPModelClass, "openai" for OpenAIModelClass, or leave empty for default ModelClass.',
|
40
47
|
)
|
41
|
-
|
48
|
+
@click.option(
|
49
|
+
'--github-pat',
|
50
|
+
required=False,
|
51
|
+
help='GitHub Personal Access Token for authentication when cloning private repositories.',
|
52
|
+
)
|
53
|
+
@click.option(
|
54
|
+
'--github-repo',
|
55
|
+
required=False,
|
56
|
+
help='GitHub repository URL or "user/repo" format to clone a repository from. If provided, the entire repository contents will be copied to the target directory instead of using default templates.',
|
57
|
+
)
|
58
|
+
@click.option(
|
59
|
+
'--branch',
|
60
|
+
required=False,
|
61
|
+
help='Git branch to clone from the GitHub repository. If not specified, the default branch will be used.',
|
62
|
+
)
|
63
|
+
def init(model_path, model_type_id, github_pat, github_repo, branch):
|
42
64
|
"""Initialize a new model directory structure.
|
43
65
|
|
44
66
|
Creates the following structure in the specified directory:
|
@@ -47,65 +69,113 @@ def init(model_path, model_type_id):
|
|
47
69
|
├── requirements.txt
|
48
70
|
└── config.yaml
|
49
71
|
|
72
|
+
If --github-repo is provided, the entire repository contents will be copied to the target
|
73
|
+
directory instead of using default templates. The --github-pat option can be used for authentication
|
74
|
+
when cloning private repositories. The --branch option can be used to specify a specific
|
75
|
+
branch to clone from.
|
76
|
+
|
50
77
|
MODEL_PATH: Path where to create the model directory structure. If not specified, the current directory is used by default.
|
51
78
|
"""
|
52
|
-
from clarifai.cli.templates.model_templates import (
|
53
|
-
get_config_template,
|
54
|
-
get_model_template,
|
55
|
-
get_requirements_template,
|
56
|
-
)
|
57
|
-
|
58
79
|
# Resolve the absolute path
|
59
80
|
model_path = os.path.abspath(model_path)
|
60
81
|
|
61
82
|
# Create the model directory if it doesn't exist
|
62
83
|
os.makedirs(model_path, exist_ok=True)
|
63
84
|
|
64
|
-
#
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
85
|
+
# Handle GitHub repository cloning if provided
|
86
|
+
if github_repo:
|
87
|
+
logger.info(f"Initializing model from GitHub repository: {github_repo}")
|
88
|
+
|
89
|
+
# Check if it's a local path or normalize the GitHub repo URL
|
90
|
+
if os.path.exists(github_repo):
|
91
|
+
repo_url = github_repo
|
92
|
+
else:
|
93
|
+
repo_url = format_github_repo_url(github_repo)
|
94
|
+
|
95
|
+
# Create a temporary directory for cloning
|
96
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
97
|
+
clone_dir = os.path.join(temp_dir, "repo")
|
98
|
+
|
99
|
+
# Clone the repository
|
100
|
+
if not clone_github_repo(repo_url, clone_dir, github_pat, branch):
|
101
|
+
logger.error(
|
102
|
+
"Failed to clone repository. Falling back to template-based initialization."
|
103
|
+
)
|
104
|
+
github_repo = None # Fall back to template mode
|
105
|
+
else:
|
106
|
+
# Copy the entire repository content to target directory (excluding .git)
|
107
|
+
for item in os.listdir(clone_dir):
|
108
|
+
if item == '.git':
|
109
|
+
continue
|
110
|
+
|
111
|
+
source_path = os.path.join(clone_dir, item)
|
112
|
+
target_path = os.path.join(model_path, item)
|
113
|
+
|
114
|
+
if os.path.isdir(source_path):
|
115
|
+
shutil.copytree(source_path, target_path, dirs_exist_ok=True)
|
116
|
+
else:
|
117
|
+
shutil.copy2(source_path, target_path)
|
118
|
+
|
119
|
+
logger.info("Model initialization complete with GitHub repository")
|
120
|
+
logger.info("Next steps:")
|
121
|
+
logger.info("1. Review the model configuration")
|
122
|
+
logger.info("2. Install any required dependencies manually")
|
123
|
+
logger.info("3. Test the model locally using 'clarifai model local-test'")
|
124
|
+
return
|
125
|
+
|
126
|
+
# Fall back to template-based initialization if no GitHub repo or if GitHub repo failed
|
127
|
+
if not github_repo:
|
128
|
+
from clarifai.cli.templates.model_templates import (
|
129
|
+
get_config_template,
|
130
|
+
get_model_template,
|
131
|
+
get_requirements_template,
|
132
|
+
)
|
107
133
|
|
108
|
-
|
134
|
+
# Create the 1/ subdirectory
|
135
|
+
model_version_dir = os.path.join(model_path, "1")
|
136
|
+
os.makedirs(model_version_dir, exist_ok=True)
|
137
|
+
|
138
|
+
# Create model.py
|
139
|
+
model_py_path = os.path.join(model_version_dir, "model.py")
|
140
|
+
if os.path.exists(model_py_path):
|
141
|
+
logger.warning(f"File {model_py_path} already exists, skipping...")
|
142
|
+
else:
|
143
|
+
model_template = get_model_template(model_type_id)
|
144
|
+
with open(model_py_path, 'w') as f:
|
145
|
+
f.write(model_template)
|
146
|
+
logger.info(f"Created {model_py_path}")
|
147
|
+
|
148
|
+
# Create requirements.txt
|
149
|
+
requirements_path = os.path.join(model_path, "requirements.txt")
|
150
|
+
if os.path.exists(requirements_path):
|
151
|
+
logger.warning(f"File {requirements_path} already exists, skipping...")
|
152
|
+
else:
|
153
|
+
requirements_template = get_requirements_template(model_type_id)
|
154
|
+
with open(requirements_path, 'w') as f:
|
155
|
+
f.write(requirements_template)
|
156
|
+
logger.info(f"Created {requirements_path}")
|
157
|
+
|
158
|
+
# Create config.yaml
|
159
|
+
config_path = os.path.join(model_path, "config.yaml")
|
160
|
+
if os.path.exists(config_path):
|
161
|
+
logger.warning(f"File {config_path} already exists, skipping...")
|
162
|
+
else:
|
163
|
+
config_model_type_id = "text-to-text" # default
|
164
|
+
|
165
|
+
config_template = get_config_template(config_model_type_id)
|
166
|
+
with open(config_path, 'w') as f:
|
167
|
+
f.write(config_template)
|
168
|
+
logger.info(f"Created {config_path}")
|
169
|
+
|
170
|
+
logger.info(f"Model initialization complete in {model_path}")
|
171
|
+
logger.info("Next steps:")
|
172
|
+
logger.info("1. Search for '# TODO: please fill in' comments in the generated files")
|
173
|
+
logger.info("2. Update the model configuration in config.yaml")
|
174
|
+
logger.info("3. Add your model dependencies to requirements.txt")
|
175
|
+
logger.info("4. Implement your model logic in 1/model.py")
|
176
|
+
|
177
|
+
|
178
|
+
@model.command(help="Upload a trained model.")
|
109
179
|
@click.argument("model_path", type=click.Path(exists=True), required=False, default=".")
|
110
180
|
@click.option(
|
111
181
|
'--stage',
|
@@ -138,7 +208,7 @@ def upload(ctx, model_path, stage, skip_dockerfile):
|
|
138
208
|
)
|
139
209
|
|
140
210
|
|
141
|
-
@model.command()
|
211
|
+
@model.command(help="Download model checkpoint files.")
|
142
212
|
@click.argument(
|
143
213
|
"model_path",
|
144
214
|
type=click.Path(exists=True),
|
@@ -172,7 +242,7 @@ def download_checkpoints(model_path, out_path, stage):
|
|
172
242
|
builder.download_checkpoints(stage=stage, checkpoint_path_override=out_path)
|
173
243
|
|
174
244
|
|
175
|
-
@model.command()
|
245
|
+
@model.command(help="Generate model method signatures.")
|
176
246
|
@click.argument(
|
177
247
|
"model_path",
|
178
248
|
type=click.Path(exists=True),
|
@@ -203,7 +273,7 @@ def signatures(model_path, out_path):
|
|
203
273
|
click.echo(signatures)
|
204
274
|
|
205
275
|
|
206
|
-
@model.command()
|
276
|
+
@model.command(name="local-test", help="Execute all model unit tests locally.")
|
207
277
|
@click.argument(
|
208
278
|
"model_path",
|
209
279
|
type=click.Path(exists=True),
|
@@ -262,7 +332,7 @@ def test_locally(model_path, keep_env=False, keep_image=False, mode='env', skip_
|
|
262
332
|
click.echo(f"Failed to test model locally: {e}", err=True)
|
263
333
|
|
264
334
|
|
265
|
-
@model.command()
|
335
|
+
@model.command(name="local-grpc", help="Run the model locally via a gRPC server.")
|
266
336
|
@click.argument(
|
267
337
|
"model_path",
|
268
338
|
type=click.Path(exists=True),
|
@@ -330,7 +400,7 @@ def run_locally(model_path, port, mode, keep_env, keep_image, skip_dockerfile=Fa
|
|
330
400
|
click.echo(f"Failed to starts model server locally: {e}", err=True)
|
331
401
|
|
332
402
|
|
333
|
-
@model.command()
|
403
|
+
@model.command(name="local-runner", help="Run the model locally for dev, debug, or local compute.")
|
334
404
|
@click.argument(
|
335
405
|
"model_path",
|
336
406
|
type=click.Path(exists=True),
|
@@ -494,7 +564,13 @@ def local_dev(ctx, model_path):
|
|
494
564
|
)
|
495
565
|
if y.lower() != 'y':
|
496
566
|
raise click.Abort()
|
497
|
-
|
567
|
+
try:
|
568
|
+
model_type_id = ctx.obj.current.model_type_id
|
569
|
+
except AttributeError:
|
570
|
+
model_type_id = DEFAULT_LOCAL_DEV_MODEL_TYPE
|
571
|
+
|
572
|
+
model = app.create_model(model_id, model_type_id=model_type_id)
|
573
|
+
ctx.obj.current.CLARIFAI_MODEL_TYPE_ID = model_type_id
|
498
574
|
ctx.obj.current.CLARIFAI_MODEL_ID = model_id
|
499
575
|
ctx.obj.to_yaml() # save to yaml file.
|
500
576
|
|
@@ -613,6 +689,7 @@ def local_dev(ctx, model_path):
|
|
613
689
|
f"config.yaml not found in {model_path}. Please ensure you are passing the correct directory."
|
614
690
|
)
|
615
691
|
config = ModelBuilder._load_config(config_file)
|
692
|
+
model_type_id = config.get('model', {}).get('model_type_id', DEFAULT_LOCAL_DEV_MODEL_TYPE)
|
616
693
|
# The config.yaml doens't match what we created above.
|
617
694
|
if 'model' in config and model_id != config['model'].get('id'):
|
618
695
|
logger.info(f"Current model section of config.yaml: {config.get('model', {})}")
|
@@ -622,7 +699,7 @@ def local_dev(ctx, model_path):
|
|
622
699
|
if y.lower() != 'y':
|
623
700
|
raise click.Abort()
|
624
701
|
config = ModelBuilder._set_local_dev_model(
|
625
|
-
config, user_id, app_id, model_id,
|
702
|
+
config, user_id, app_id, model_id, model_type_id
|
626
703
|
)
|
627
704
|
ModelBuilder._backup_config(config_file)
|
628
705
|
ModelBuilder._save_config(config_file, config)
|
@@ -663,7 +740,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
|
663
740
|
)
|
664
741
|
|
665
742
|
|
666
|
-
@model.command()
|
743
|
+
@model.command(help="Perform a prediction using the model.")
|
667
744
|
@click.option(
|
668
745
|
'--config',
|
669
746
|
type=click.Path(exists=True),
|
@@ -845,7 +922,7 @@ def predict(
|
|
845
922
|
)
|
846
923
|
@click.pass_context
|
847
924
|
def list_model(ctx, user_id, app_id):
|
848
|
-
"""List models of user/community
|
925
|
+
"""List models of user/community.
|
849
926
|
|
850
927
|
USER_ID: User id. If not specified, the current user is used by default. Set "all" to get all public models in Clarifai platform.
|
851
928
|
"""
|
@@ -66,6 +66,7 @@ class Model(Lister, BaseClient):
|
|
66
66
|
compute_cluster_id: str = None,
|
67
67
|
nodepool_id: str = None,
|
68
68
|
deployment_id: str = None,
|
69
|
+
deployment_user_id: str = None,
|
69
70
|
**kwargs,
|
70
71
|
):
|
71
72
|
"""Initializes a Model object.
|
@@ -78,6 +79,10 @@ class Model(Lister, BaseClient):
|
|
78
79
|
pat (str): A personal access token for authentication. Can be set as env var CLARIFAI_PAT
|
79
80
|
token (str): A session token for authentication. Accepts either a session token or a pat. Can be set as env var CLARIFAI_SESSION_TOKEN
|
80
81
|
root_certificates_path (str): Path to the SSL root certificates file, used to establish secure gRPC connections.
|
82
|
+
compute_cluster_id (str): Compute cluster ID for runner selector.
|
83
|
+
nodepool_id (str): Nodepool ID for runner selector.
|
84
|
+
deployment_id (str): Deployment ID for runner selector.
|
85
|
+
deployment_user_id (str): User ID to use for runner selector (organization or user). If not provided, defaults to PAT owner user_id.
|
81
86
|
**kwargs: Additional keyword arguments to be passed to the Model.
|
82
87
|
"""
|
83
88
|
if url and model_id:
|
@@ -115,10 +120,13 @@ class Model(Lister, BaseClient):
|
|
115
120
|
)
|
116
121
|
Lister.__init__(self)
|
117
122
|
|
123
|
+
self.deployment_user_id = deployment_user_id
|
124
|
+
|
118
125
|
self._set_runner_selector(
|
119
126
|
compute_cluster_id=compute_cluster_id,
|
120
127
|
nodepool_id=nodepool_id,
|
121
128
|
deployment_id=deployment_id,
|
129
|
+
deployment_user_id=deployment_user_id,
|
122
130
|
)
|
123
131
|
|
124
132
|
@classmethod
|
@@ -633,9 +641,13 @@ class Model(Lister, BaseClient):
|
|
633
641
|
compute_cluster_id: str = None,
|
634
642
|
nodepool_id: str = None,
|
635
643
|
deployment_id: str = None,
|
644
|
+
deployment_user_id: str = None,
|
636
645
|
):
|
637
|
-
# Get UserID
|
638
|
-
|
646
|
+
# Get UserID for runner selector
|
647
|
+
user_id = None
|
648
|
+
if deployment_user_id:
|
649
|
+
user_id = deployment_user_id
|
650
|
+
elif any([deployment_id, nodepool_id, compute_cluster_id]):
|
639
651
|
from clarifai.client.user import User
|
640
652
|
|
641
653
|
user_id = (
|
@@ -643,13 +655,11 @@ class Model(Lister, BaseClient):
|
|
643
655
|
.get_user_info(user_id='me')
|
644
656
|
.user.id
|
645
657
|
)
|
646
|
-
|
647
658
|
runner_selector = None
|
648
659
|
if deployment_id and (compute_cluster_id or nodepool_id):
|
649
660
|
raise UserError(
|
650
661
|
"You can only specify one of deployment_id or compute_cluster_id and nodepool_id."
|
651
662
|
)
|
652
|
-
|
653
663
|
if deployment_id:
|
654
664
|
runner_selector = Deployment.get_runner_selector(
|
655
665
|
user_id=user_id, deployment_id=deployment_id
|
@@ -658,7 +668,6 @@ class Model(Lister, BaseClient):
|
|
658
668
|
runner_selector = Nodepool.get_runner_selector(
|
659
669
|
user_id=user_id, compute_cluster_id=compute_cluster_id, nodepool_id=nodepool_id
|
660
670
|
)
|
661
|
-
|
662
671
|
# set the runner selector
|
663
672
|
self._runner_selector = runner_selector
|
664
673
|
|
@@ -127,7 +127,7 @@ from clarifai.runners.utils import data_types
|
|
127
127
|
|
128
128
|
base_url_str = ""
|
129
129
|
if base_url is not None:
|
130
|
-
base_url_str = f"base_url={base_url},"
|
130
|
+
base_url_str = f"base_url='{base_url}',"
|
131
131
|
|
132
132
|
# Join all non-empty lines
|
133
133
|
optional_lines = "\n ".join(
|
@@ -321,7 +321,10 @@ def _set_default_value(field_type):
|
|
321
321
|
default_value = f"{{{', '.join([str(et) for et in element_type_defaults])}}}"
|
322
322
|
|
323
323
|
if is_iterator:
|
324
|
-
|
324
|
+
if field_type == "str":
|
325
|
+
default_value = f"iter(['{default_value}'])"
|
326
|
+
else:
|
327
|
+
default_value = f"iter([{default_value}])"
|
325
328
|
return default_value
|
326
329
|
|
327
330
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import os
|
2
|
+
from pathlib import Path
|
2
3
|
|
3
4
|
DEFAULT_UI = os.environ.get("CLARIFAI_UI", "https://clarifai.com")
|
4
5
|
DEFAULT_BASE = os.environ.get("CLARIFAI_API_BASE", "https://api.clarifai.com")
|
@@ -10,7 +11,8 @@ CLARIFAI_PAT_ENV_VAR = "CLARIFAI_PAT"
|
|
10
11
|
CLARIFAI_SESSION_TOKEN_ENV_VAR = "CLARIFAI_SESSION_TOKEN"
|
11
12
|
CLARIFAI_USER_ID_ENV_VAR = "CLARIFAI_USER_ID"
|
12
13
|
|
13
|
-
|
14
|
+
HOME_PATH = Path.home()
|
15
|
+
DEFAULT_CONFIG = HOME_PATH / '.config/clarifai/config'
|
14
16
|
|
15
17
|
# Default clusters, etc. for local dev runner easy setup
|
16
18
|
DEFAULT_LOCAL_DEV_COMPUTE_CLUSTER_ID = "local-dev-compute-cluster"
|
@@ -45,7 +47,7 @@ DEFAULT_LOCAL_DEV_NODEPOOL_CONFIG = {
|
|
45
47
|
},
|
46
48
|
"instance_types": [
|
47
49
|
{
|
48
|
-
"id": "local
|
50
|
+
"id": "local",
|
49
51
|
"compute_info": {
|
50
52
|
"cpu_limit": str(os.cpu_count()),
|
51
53
|
"cpu_memory": "16Gi", # made up as we don't schedule based on this for local dev.
|
@@ -1,11 +1,16 @@
|
|
1
1
|
import os
|
2
2
|
import re
|
3
|
+
import shutil
|
4
|
+
import subprocess
|
5
|
+
import urllib.parse
|
3
6
|
import uuid
|
4
7
|
from typing import Any, Dict, List
|
5
8
|
|
6
9
|
from clarifai_grpc.grpc.api.status import status_code_pb2
|
7
10
|
|
8
11
|
from clarifai.errors import UserError
|
12
|
+
from clarifai.utils.constants import HOME_PATH
|
13
|
+
from clarifai.utils.logging import logger
|
9
14
|
|
10
15
|
RETRYABLE_CODES = [
|
11
16
|
status_code_pb2.MODEL_DEPLOYING,
|
@@ -13,7 +18,7 @@ RETRYABLE_CODES = [
|
|
13
18
|
status_code_pb2.MODEL_BUSY_PLEASE_RETRY,
|
14
19
|
]
|
15
20
|
|
16
|
-
DEFAULT_CONFIG =
|
21
|
+
DEFAULT_CONFIG = HOME_PATH / '.config/clarifai/config'
|
17
22
|
|
18
23
|
|
19
24
|
def status_is_retryable(status_code: int) -> bool:
|
@@ -104,3 +109,60 @@ def clean_input_id(input_id: str) -> str:
|
|
104
109
|
input_id = input_id.lower().strip('_-')
|
105
110
|
input_id = re.sub('[^a-z0-9-_]+', '', input_id)
|
106
111
|
return input_id
|
112
|
+
|
113
|
+
|
114
|
+
def format_github_repo_url(github_repo):
|
115
|
+
"""Format GitHub repository URL to a standard format."""
|
116
|
+
if github_repo.startswith('http'):
|
117
|
+
return github_repo
|
118
|
+
elif '/' in github_repo and not github_repo.startswith('git@'):
|
119
|
+
# Handle "user/repo" format
|
120
|
+
return f"https://github.com/{github_repo}.git"
|
121
|
+
else:
|
122
|
+
return github_repo
|
123
|
+
|
124
|
+
|
125
|
+
def clone_github_repo(repo_url, target_dir, github_pat=None, branch=None):
|
126
|
+
"""Clone a GitHub repository with optional GitHub PAT authentication and branch specification."""
|
127
|
+
# Handle local file paths - just copy instead of cloning
|
128
|
+
if os.path.exists(repo_url):
|
129
|
+
try:
|
130
|
+
shutil.copytree(repo_url, target_dir, ignore=shutil.ignore_patterns('.git'))
|
131
|
+
logger.info(f"Successfully copied local repository from {repo_url}")
|
132
|
+
return True
|
133
|
+
except Exception as e:
|
134
|
+
logger.error(f"Failed to copy local repository: {e}")
|
135
|
+
return False
|
136
|
+
|
137
|
+
cmd = ["git", "clone"]
|
138
|
+
|
139
|
+
# Add branch specification if provided
|
140
|
+
if branch:
|
141
|
+
cmd.extend(["-b", branch])
|
142
|
+
|
143
|
+
# Handle authentication with GitHub PAT
|
144
|
+
if github_pat:
|
145
|
+
# Parse the URL and validate the hostname
|
146
|
+
parsed_url = urllib.parse.urlparse(repo_url)
|
147
|
+
if parsed_url.hostname == "github.com":
|
148
|
+
# Insert GitHub PAT into the URL for authentication
|
149
|
+
authenticated_url = f"https://{github_pat}@{parsed_url.netloc}{parsed_url.path}"
|
150
|
+
cmd.append(authenticated_url)
|
151
|
+
else:
|
152
|
+
logger.error(f"Invalid repository URL: {repo_url}")
|
153
|
+
return False
|
154
|
+
else:
|
155
|
+
cmd.append(repo_url)
|
156
|
+
|
157
|
+
cmd.append(target_dir)
|
158
|
+
|
159
|
+
try:
|
160
|
+
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
161
|
+
if branch:
|
162
|
+
logger.info(f"Successfully cloned repository from {repo_url} (branch: {branch})")
|
163
|
+
else:
|
164
|
+
logger.info(f"Successfully cloned repository from {repo_url}")
|
165
|
+
return True
|
166
|
+
except subprocess.CalledProcessError as e:
|
167
|
+
logger.error(f"Failed to clone repository: {e.stderr}")
|
168
|
+
return False
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: clarifai
|
3
|
-
Version: 11.6.
|
3
|
+
Version: 11.6.2
|
4
4
|
Home-page: https://github.com/Clarifai/clarifai-python
|
5
5
|
Author: Clarifai
|
6
6
|
Author-email: support@clarifai.com
|
@@ -19,7 +19,7 @@ Classifier: Operating System :: OS Independent
|
|
19
19
|
Requires-Python: >=3.8
|
20
20
|
Description-Content-Type: text/markdown
|
21
21
|
License-File: LICENSE
|
22
|
-
Requires-Dist: clarifai-grpc>=11.
|
22
|
+
Requires-Dist: clarifai-grpc>=11.6.0
|
23
23
|
Requires-Dist: clarifai-protocol>=0.0.25
|
24
24
|
Requires-Dist: numpy>=1.22.0
|
25
25
|
Requires-Dist: tqdm>=4.65.0
|
@@ -1 +0,0 @@
|
|
1
|
-
__version__ = "11.6.0"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{clarifai-11.6.0 → clarifai-11.6.2}/clarifai/datasets/upload/loaders/imagenet_classification.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/dockerfile_template/Dockerfile.template
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{clarifai-11.6.0 → clarifai-11.6.2}/clarifai/runners/pipeline_steps/pipeline_step_builder.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|