clarifai 11.3.0rc2__py3-none-any.whl → 11.4.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/__main__.py +1 -1
- clarifai/cli/base.py +144 -136
- clarifai/cli/compute_cluster.py +45 -31
- clarifai/cli/deployment.py +93 -76
- clarifai/cli/model.py +578 -180
- clarifai/cli/nodepool.py +100 -82
- clarifai/client/__init__.py +12 -2
- clarifai/client/app.py +973 -911
- clarifai/client/auth/helper.py +345 -342
- clarifai/client/auth/register.py +7 -7
- clarifai/client/auth/stub.py +107 -106
- clarifai/client/base.py +185 -178
- clarifai/client/compute_cluster.py +214 -180
- clarifai/client/dataset.py +793 -698
- clarifai/client/deployment.py +55 -50
- clarifai/client/input.py +1223 -1088
- clarifai/client/lister.py +47 -45
- clarifai/client/model.py +1939 -1717
- clarifai/client/model_client.py +525 -502
- clarifai/client/module.py +82 -73
- clarifai/client/nodepool.py +358 -213
- clarifai/client/runner.py +58 -0
- clarifai/client/search.py +342 -309
- clarifai/client/user.py +419 -414
- clarifai/client/workflow.py +294 -274
- clarifai/constants/dataset.py +11 -17
- clarifai/constants/model.py +8 -2
- clarifai/datasets/export/inputs_annotations.py +233 -217
- clarifai/datasets/upload/base.py +63 -51
- clarifai/datasets/upload/features.py +43 -38
- clarifai/datasets/upload/image.py +237 -207
- clarifai/datasets/upload/loaders/coco_captions.py +34 -32
- clarifai/datasets/upload/loaders/coco_detection.py +72 -65
- clarifai/datasets/upload/loaders/imagenet_classification.py +57 -53
- clarifai/datasets/upload/loaders/xview_detection.py +274 -132
- clarifai/datasets/upload/multimodal.py +55 -46
- clarifai/datasets/upload/text.py +55 -47
- clarifai/datasets/upload/utils.py +250 -234
- clarifai/errors.py +51 -50
- clarifai/models/api.py +260 -238
- clarifai/modules/css.py +50 -50
- clarifai/modules/pages.py +33 -33
- clarifai/rag/rag.py +312 -288
- clarifai/rag/utils.py +91 -84
- clarifai/runners/models/model_builder.py +906 -802
- clarifai/runners/models/model_class.py +370 -331
- clarifai/runners/models/model_run_locally.py +459 -419
- clarifai/runners/models/model_runner.py +170 -162
- clarifai/runners/models/model_servicer.py +78 -70
- clarifai/runners/server.py +111 -101
- clarifai/runners/utils/code_script.py +225 -187
- clarifai/runners/utils/const.py +4 -1
- clarifai/runners/utils/data_types/__init__.py +12 -0
- clarifai/runners/utils/data_types/data_types.py +598 -0
- clarifai/runners/utils/data_utils.py +387 -440
- clarifai/runners/utils/loader.py +247 -227
- clarifai/runners/utils/method_signatures.py +411 -386
- clarifai/runners/utils/openai_convertor.py +108 -109
- clarifai/runners/utils/serializers.py +175 -179
- clarifai/runners/utils/url_fetcher.py +35 -35
- clarifai/schema/search.py +56 -63
- clarifai/urls/helper.py +125 -102
- clarifai/utils/cli.py +129 -123
- clarifai/utils/config.py +127 -87
- clarifai/utils/constants.py +49 -0
- clarifai/utils/evaluation/helpers.py +503 -466
- clarifai/utils/evaluation/main.py +431 -393
- clarifai/utils/evaluation/testset_annotation_parser.py +154 -144
- clarifai/utils/logging.py +324 -306
- clarifai/utils/misc.py +60 -56
- clarifai/utils/model_train.py +165 -146
- clarifai/utils/protobuf.py +126 -103
- clarifai/versions.py +3 -1
- clarifai/workflows/export.py +48 -50
- clarifai/workflows/utils.py +39 -36
- clarifai/workflows/validate.py +55 -43
- {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info}/METADATA +16 -6
- clarifai-11.4.0.dist-info/RECORD +109 -0
- {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info}/WHEEL +1 -1
- clarifai/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/__pycache__/errors.cpython-310.pyc +0 -0
- clarifai/__pycache__/errors.cpython-311.pyc +0 -0
- clarifai/__pycache__/versions.cpython-310.pyc +0 -0
- clarifai/__pycache__/versions.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/base.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/base_cli.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/compute_cluster.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/compute_cluster.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/deployment.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/deployment.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/model.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/model.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/model_cli.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/nodepool.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/nodepool.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/client/__pycache__/app.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/app.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/app.cpython-39.pyc +0 -0
- clarifai/client/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/base.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/compute_cluster.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/compute_cluster.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/dataset.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/dataset.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/deployment.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/deployment.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/input.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/input.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/lister.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/lister.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/model.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/model.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/module.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/module.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/nodepool.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/nodepool.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/search.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/search.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/user.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/user.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/workflow.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/workflow.cpython-311.pyc +0 -0
- clarifai/client/auth/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/client/auth/__pycache__/helper.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/helper.cpython-311.pyc +0 -0
- clarifai/client/auth/__pycache__/register.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/register.cpython-311.pyc +0 -0
- clarifai/client/auth/__pycache__/stub.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/stub.cpython-311.pyc +0 -0
- clarifai/client/cli/__init__.py +0 -0
- clarifai/client/cli/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/client/cli/__pycache__/base_cli.cpython-310.pyc +0 -0
- clarifai/client/cli/__pycache__/model_cli.cpython-310.pyc +0 -0
- clarifai/client/cli/base_cli.py +0 -88
- clarifai/client/cli/model_cli.py +0 -29
- clarifai/constants/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/base.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/dataset.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/dataset.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/input.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/input.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/model.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/model.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/rag.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/rag.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/search.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/search.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/workflow.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/workflow.cpython-311.pyc +0 -0
- clarifai/datasets/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/datasets/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/datasets/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/datasets/export/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/datasets/export/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/datasets/export/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/datasets/export/__pycache__/inputs_annotations.cpython-310.pyc +0 -0
- clarifai/datasets/export/__pycache__/inputs_annotations.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/datasets/upload/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/base.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/features.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/features.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/image.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/image.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/multimodal.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/multimodal.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/text.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/text.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/utils.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/utils.cpython-311.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/coco_detection.cpython-311.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/imagenet_classification.cpython-311.pyc +0 -0
- clarifai/models/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/modules/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/rag/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/rag/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/rag/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/rag/__pycache__/rag.cpython-310.pyc +0 -0
- clarifai/rag/__pycache__/rag.cpython-311.pyc +0 -0
- clarifai/rag/__pycache__/rag.cpython-39.pyc +0 -0
- clarifai/rag/__pycache__/utils.cpython-310.pyc +0 -0
- clarifai/rag/__pycache__/utils.cpython-311.pyc +0 -0
- clarifai/runners/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/runners/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/runners/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/runners/dockerfile_template/Dockerfile.cpu.template +0 -31
- clarifai/runners/dockerfile_template/Dockerfile.cuda.template +0 -42
- clarifai/runners/dockerfile_template/Dockerfile.nim +0 -71
- clarifai/runners/models/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/runners/models/__pycache__/base_typed_model.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/base_typed_model.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/base_typed_model.cpython-39.pyc +0 -0
- clarifai/runners/models/__pycache__/model_builder.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/model_class.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_class.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/model_run_locally.cpython-310-pytest-7.1.2.pyc +0 -0
- clarifai/runners/models/__pycache__/model_run_locally.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_run_locally.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/model_runner.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_runner.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/model_upload.cpython-310.pyc +0 -0
- clarifai/runners/models/base_typed_model.py +0 -238
- clarifai/runners/models/model_class_refract.py +0 -80
- clarifai/runners/models/model_upload.py +0 -607
- clarifai/runners/models/temp.py +0 -25
- clarifai/runners/utils/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/__init__.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/buffered_stream.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/buffered_stream.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/buffered_stream.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/const.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/const.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/constants.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/constants.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/constants.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_handler.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_handler.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_handler.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_handler.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_utils.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_utils.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_utils.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_utils.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/grpc_server.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/grpc_server.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/grpc_server.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/health.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/health.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/health.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/loader.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/loader.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/logging.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/logging.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/logging.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/stream_source.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/stream_source.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/url_fetcher.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/url_fetcher.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/url_fetcher.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/url_fetcher.cpython-39.pyc +0 -0
- clarifai/runners/utils/data_handler.py +0 -231
- clarifai/runners/utils/data_handler_refract.py +0 -213
- clarifai/runners/utils/data_types.py +0 -469
- clarifai/runners/utils/logger.py +0 -0
- clarifai/runners/utils/openai_format.py +0 -87
- clarifai/schema/__pycache__/search.cpython-310.pyc +0 -0
- clarifai/schema/__pycache__/search.cpython-311.pyc +0 -0
- clarifai/urls/__pycache__/helper.cpython-310.pyc +0 -0
- clarifai/urls/__pycache__/helper.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/utils/__pycache__/cli.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/cli.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/config.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/constants.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/constants.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/logging.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/logging.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/misc.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/misc.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/model_train.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/model_train.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/protobuf.cpython-311.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/helpers.cpython-311.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/main.cpython-311.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/main.cpython-39.pyc +0 -0
- clarifai/workflows/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/workflows/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/workflows/__pycache__/export.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/export.cpython-311.pyc +0 -0
- clarifai/workflows/__pycache__/utils.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/utils.cpython-311.pyc +0 -0
- clarifai/workflows/__pycache__/validate.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/validate.cpython-311.pyc +0 -0
- clarifai-11.3.0rc2.dist-info/RECORD +0 -322
- {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info}/entry_points.txt +0 -0
- {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info/licenses}/LICENSE +0 -0
- {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info}/top_level.txt +0 -0
clarifai/utils/protobuf.py
CHANGED
@@ -19,125 +19,148 @@ WRAPPER_TYPES = {
|
|
19
19
|
|
20
20
|
|
21
21
|
def dict_to_protobuf(pb_obj: Message, data: dict) -> None:
|
22
|
-
|
22
|
+
"""Recursively convert a nested dictionary to a Protobuf message object.
|
23
23
|
|
24
24
|
Args:
|
25
25
|
pb_obj: The target Protobuf message instance to populate.
|
26
26
|
data: Source dictionary containing the data to convert.
|
27
27
|
"""
|
28
|
-
for field, value in data.items():
|
29
|
-
if field not in pb_obj.DESCRIPTOR.fields_by_name:
|
30
|
-
logger.warning(f"Ignoring unknown field '{field}' in message '{pb_obj.DESCRIPTOR.name}'")
|
31
|
-
continue
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
29
|
+
for field, value in data.items():
|
30
|
+
if field not in pb_obj.DESCRIPTOR.fields_by_name:
|
31
|
+
logger.warning(
|
32
|
+
f"Ignoring unknown field '{field}' in message '{pb_obj.DESCRIPTOR.name}'"
|
33
|
+
)
|
34
|
+
continue
|
35
|
+
|
36
|
+
field_descriptor = pb_obj.DESCRIPTOR.fields_by_name[field]
|
37
|
+
|
38
|
+
try:
|
39
|
+
# Handle repeated fields (lists)
|
40
|
+
if field_descriptor.label == FieldDescriptor.LABEL_REPEATED:
|
41
|
+
_handle_repeated_field(pb_obj, field_descriptor, field, value)
|
42
|
+
|
43
|
+
# Handle message fields (nested messages)
|
44
|
+
elif field_descriptor.type == FieldDescriptor.TYPE_MESSAGE:
|
45
|
+
_handle_message_field(pb_obj, field_descriptor, field, value)
|
46
|
+
|
47
|
+
# Handle enums as string or int.
|
48
|
+
# Alternative is to use MessageToDict with use_integers_for_enums=True everywhere
|
49
|
+
# we end up calling dict_to_protobuf afterwards.
|
50
|
+
elif field_descriptor.type == FieldDescriptor.TYPE_ENUM:
|
51
|
+
if isinstance(value, str):
|
52
|
+
enum_value = field_descriptor.enum_type.values_by_name.get(value)
|
53
|
+
if enum_value is not None:
|
54
|
+
setattr(pb_obj, field, enum_value.number)
|
55
|
+
elif isinstance(value, int):
|
56
|
+
enum_value = field_descriptor.enum_type.values_by_number.get(value)
|
57
|
+
if enum_value is not None:
|
58
|
+
setattr(pb_obj, field, enum_value.number)
|
59
|
+
|
60
|
+
# Handle scalar fields
|
61
|
+
elif value:
|
62
|
+
setattr(pb_obj, field, value)
|
63
|
+
|
64
|
+
except Exception as e:
|
65
|
+
logger.error(f"Error processing field '{field}': {str(e)}")
|
66
|
+
raise
|
67
|
+
|
68
|
+
|
69
|
+
def _handle_repeated_field(
|
70
|
+
pb_obj: Message, field_descriptor: FieldDescriptor, field: str, value: list
|
71
|
+
) -> None:
|
72
|
+
"""Process repeated fields (both scalar and message types)."""
|
73
|
+
if not isinstance(value, list):
|
74
|
+
logger.warning(f"Expected list for repeated field '{field}', got {type(value).__name__}")
|
75
|
+
return
|
76
|
+
|
77
|
+
repeated_field = getattr(pb_obj, field)
|
78
|
+
|
79
|
+
# Handle repeated message fields
|
80
|
+
if field_descriptor.type == FieldDescriptor.TYPE_MESSAGE:
|
81
|
+
for item in value:
|
82
|
+
if isinstance(item, dict):
|
83
|
+
item_msg = repeated_field.add()
|
84
|
+
dict_to_protobuf(item_msg, item)
|
85
|
+
elif isinstance(item, Message):
|
86
|
+
repeated_field.add().CopyFrom(item)
|
87
|
+
else:
|
88
|
+
logger.warning(
|
89
|
+
f"Invalid type {type(item).__name__} in repeated message field '{field}'"
|
90
|
+
)
|
91
|
+
else:
|
92
|
+
# Handle repeated scalar fields
|
93
|
+
try:
|
94
|
+
repeated_field.extend(value)
|
95
|
+
except TypeError as e:
|
96
|
+
logger.error(f"Type mismatch in repeated scalar field '{field}': {str(e)}")
|
97
|
+
raise
|
98
|
+
|
99
|
+
|
100
|
+
def _handle_message_field(
|
101
|
+
pb_obj: Message, field_descriptor: FieldDescriptor, field: str, value: object
|
102
|
+
) -> None:
|
103
|
+
"""Process message-type fields including special types."""
|
104
|
+
msg_class = db.GetSymbol(field_descriptor.message_type.full_name)
|
105
|
+
target_field = getattr(pb_obj, field)
|
106
|
+
|
107
|
+
# Handle special message types
|
108
|
+
if msg_class is Timestamp:
|
109
|
+
_set_timestamp_value(target_field, value)
|
110
|
+
elif msg_class is struct_pb2.Struct:
|
111
|
+
_set_struct_value(target_field, value)
|
112
|
+
elif msg_class in WRAPPER_TYPES:
|
113
|
+
_set_wrapper_value(target_field, msg_class, value)
|
96
114
|
# Handle nested messages
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
115
|
+
elif isinstance(value, dict):
|
116
|
+
nested_pb = msg_class()
|
117
|
+
dict_to_protobuf(nested_pb, value)
|
118
|
+
target_field.CopyFrom(nested_pb)
|
101
119
|
elif isinstance(value, Message):
|
102
|
-
|
120
|
+
target_field.CopyFrom(value)
|
103
121
|
else:
|
104
|
-
|
122
|
+
logger.warning(f"Invalid type {type(value).__name__} for message field '{field}'")
|
105
123
|
|
106
124
|
|
107
125
|
def _set_timestamp_value(target_field: Message, value: object) -> None:
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
126
|
+
"""Set timestamp value from dict or numeric timestamp."""
|
127
|
+
ts = Timestamp()
|
128
|
+
if isinstance(value, dict):
|
129
|
+
ts.seconds = value.get('seconds', 0)
|
130
|
+
ts.nanos = value.get('nanos', 0)
|
131
|
+
elif isinstance(value, (int, float)):
|
132
|
+
ts.seconds = int(value)
|
133
|
+
ts.nanos = int((value - ts.seconds) * 1e9)
|
134
|
+
elif isinstance(value, Timestamp):
|
135
|
+
ts = value
|
136
|
+
else:
|
137
|
+
logger.warning(f"Unsupported timestamp format: {type(value).__name__}")
|
138
|
+
target_field.CopyFrom(ts)
|
119
139
|
|
120
140
|
|
121
141
|
def _set_struct_value(target_field: Message, value: object) -> None:
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
142
|
+
"""Convert dictionary to Protobuf Struct."""
|
143
|
+
if isinstance(value, struct_pb2.Struct):
|
144
|
+
struct = value
|
145
|
+
else:
|
146
|
+
if not isinstance(value, dict):
|
147
|
+
logger.warning(f"Expected dict for Struct field, got {type(value).__name__}")
|
148
|
+
return
|
126
149
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
150
|
+
struct = struct_pb2.Struct()
|
151
|
+
try:
|
152
|
+
struct.update(value)
|
153
|
+
except ValueError as e:
|
154
|
+
logger.error(f"Invalid value in Struct: {str(e)}")
|
155
|
+
raise
|
156
|
+
target_field.CopyFrom(struct)
|
134
157
|
|
135
158
|
|
136
159
|
def _set_wrapper_value(target_field: Message, wrapper_type: type, value: object) -> None:
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
160
|
+
"""Set value for wrapper types (e.g., Int32Value)."""
|
161
|
+
try:
|
162
|
+
wrapper = wrapper_type(value=value)
|
163
|
+
except TypeError as e:
|
164
|
+
logger.error(f"Invalid value for {wrapper_type.__name__}: {str(e)}")
|
165
|
+
raise
|
166
|
+
target_field.CopyFrom(wrapper)
|
clarifai/versions.py
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
import os
|
2
|
+
|
2
3
|
from clarifai import __version__
|
3
4
|
|
4
5
|
CLIENT_VERSION = __version__
|
5
6
|
OS_VER = os.sys.platform
|
6
7
|
PYTHON_VERSION = '.'.join(
|
7
|
-
map(str, [os.sys.version_info.major, os.sys.version_info.minor, os.sys.version_info.micro])
|
8
|
+
map(str, [os.sys.version_info.major, os.sys.version_info.minor, os.sys.version_info.micro])
|
9
|
+
)
|
clarifai/workflows/export.py
CHANGED
@@ -7,62 +7,60 @@ VALID_YAML_KEYS = ["workflow", "id", "nodes", "node_inputs", "node_id", "model"]
|
|
7
7
|
|
8
8
|
|
9
9
|
def clean_up_unused_keys(wf: dict):
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
return new_wf
|
10
|
+
"""Removes unused keys from dict before exporting to yaml. Supports nested dicts."""
|
11
|
+
new_wf = dict()
|
12
|
+
for key, val in wf.items():
|
13
|
+
if key not in VALID_YAML_KEYS:
|
14
|
+
continue
|
15
|
+
if key == "model":
|
16
|
+
new_wf["model"] = {
|
17
|
+
"model_id": wf["model"]["id"],
|
18
|
+
"model_version_id": wf["model"]["model_version"]["id"],
|
19
|
+
}
|
20
|
+
# If the model is not from clarifai main, add the app_id and user_id to the model dict.
|
21
|
+
if wf["model"]["user_id"] != "clarifai" and wf["model"]["app_id"] != "main":
|
22
|
+
new_wf["model"].update(
|
23
|
+
{"app_id": wf["model"]["app_id"], "user_id": wf["model"]["user_id"]}
|
24
|
+
)
|
25
|
+
elif isinstance(val, dict):
|
26
|
+
new_wf[key] = clean_up_unused_keys(val)
|
27
|
+
elif isinstance(val, list):
|
28
|
+
new_list = []
|
29
|
+
for i in val:
|
30
|
+
new_list.append(clean_up_unused_keys(i))
|
31
|
+
new_wf[key] = new_list
|
32
|
+
else:
|
33
|
+
new_wf[key] = val
|
34
|
+
return new_wf
|
36
35
|
|
37
36
|
|
38
37
|
class Exporter:
|
38
|
+
def __init__(self, workflow):
|
39
|
+
self.wf = workflow
|
39
40
|
|
40
|
-
|
41
|
-
|
41
|
+
def __enter__(self):
|
42
|
+
return self
|
42
43
|
|
43
|
-
|
44
|
-
|
44
|
+
def parse(self) -> Dict[str, Any]:
|
45
|
+
"""Reads a resources_pb2.Workflow object (e.g. from a GetWorkflow response)
|
45
46
|
|
46
|
-
|
47
|
-
|
47
|
+
Returns:
|
48
|
+
dict: A dict representation of the workflow.
|
49
|
+
"""
|
50
|
+
if isinstance(self.wf, list):
|
51
|
+
self.wf = self.wf[0]
|
52
|
+
wf = {"workflow": MessageToDict(self.wf, preserving_proto_field_name=True)}
|
53
|
+
clean_wf = clean_up_unused_keys(wf)
|
54
|
+
self.wf_dict = clean_wf
|
55
|
+
return clean_wf
|
48
56
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
if isinstance(self.wf, list):
|
53
|
-
self.wf = self.wf[0]
|
54
|
-
wf = {"workflow": MessageToDict(self.wf, preserving_proto_field_name=True)}
|
55
|
-
clean_wf = clean_up_unused_keys(wf)
|
56
|
-
self.wf_dict = clean_wf
|
57
|
-
return clean_wf
|
57
|
+
def export(self, out_path):
|
58
|
+
with open(out_path, 'w') as out_file:
|
59
|
+
yaml.dump(self.wf_dict["workflow"], out_file, default_flow_style=False)
|
58
60
|
|
59
|
-
|
60
|
-
|
61
|
-
yaml.dump(self.wf_dict["workflow"], out_file, default_flow_style=False)
|
61
|
+
def __exit__(self, *args):
|
62
|
+
self.close()
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
def close(self):
|
67
|
-
del self.wf
|
68
|
-
del self.wf_dict
|
64
|
+
def close(self):
|
65
|
+
del self.wf
|
66
|
+
del self.wf_dict
|
clarifai/workflows/utils.py
CHANGED
@@ -6,54 +6,57 @@ from google.protobuf.json_format import MessageToDict
|
|
6
6
|
|
7
7
|
|
8
8
|
def get_yaml_output_info_proto(yaml_model_output_info: Dict) -> Optional[resources_pb2.OutputInfo]:
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
"""Converts a yaml model output info to an api model output info."""
|
10
|
+
if not yaml_model_output_info:
|
11
|
+
return None
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
return resources_pb2.OutputInfo(
|
14
|
+
params=convert_yaml_params_to_api_params(yaml_model_output_info.get('params'))
|
15
|
+
)
|
15
16
|
|
16
17
|
|
17
18
|
def convert_yaml_params_to_api_params(yaml_params: Dict) -> Optional[struct_pb2.Struct]:
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
"""Converts a yaml model output info params to an api model output info params."""
|
20
|
+
if not yaml_params:
|
21
|
+
return None
|
21
22
|
|
22
|
-
|
23
|
-
|
23
|
+
s = struct_pb2.Struct()
|
24
|
+
s.update(yaml_params)
|
24
25
|
|
25
|
-
|
26
|
+
return s
|
26
27
|
|
27
28
|
|
28
29
|
def is_same_yaml_model(api_model: resources_pb2.Model, yaml_model: Dict) -> bool:
|
29
|
-
|
30
|
-
|
30
|
+
"""Compares a model from the API with a model from a yaml file."""
|
31
|
+
api_model = MessageToDict(api_model, preserving_proto_field_name=True)
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
yaml_model_from_api = dict()
|
34
|
+
for k, _ in yaml_model.items():
|
35
|
+
if k == "output_info" and api_model["model_version"].get("output_info", "") != "":
|
36
|
+
yaml_model_from_api[k] = dict(
|
37
|
+
params=api_model["model_version"]["output_info"].get("params")
|
38
|
+
)
|
39
|
+
else:
|
40
|
+
yaml_model_from_api[k] = api_model.get(k)
|
41
|
+
yaml_model_from_api.update({"model_id": api_model.get("id")})
|
39
42
|
|
40
|
-
|
43
|
+
ignore_keys = {}
|
41
44
|
|
42
|
-
|
45
|
+
return is_dict_in_dict(yaml_model, yaml_model_from_api, ignore_keys)
|
43
46
|
|
44
47
|
|
45
48
|
def is_dict_in_dict(d1: Dict, d2: Dict, ignore_keys: Set = None) -> bool:
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
49
|
+
"""Compares two dicts recursively."""
|
50
|
+
for k, v in d1.items():
|
51
|
+
if ignore_keys and k in ignore_keys:
|
52
|
+
continue
|
53
|
+
if k not in d2:
|
54
|
+
return False
|
55
|
+
if isinstance(v, dict):
|
56
|
+
if not isinstance(d2[k], dict):
|
57
|
+
return False
|
58
|
+
return is_dict_in_dict(d1[k], d2[k], None)
|
59
|
+
elif v != d2[k]:
|
60
|
+
return False
|
61
|
+
|
62
|
+
return True
|
clarifai/workflows/validate.py
CHANGED
@@ -8,60 +8,72 @@ _hex_id_validator = And(str, Use(str.lower), Regex(r'^[0-9a-f]{32}'))
|
|
8
8
|
|
9
9
|
|
10
10
|
def _model_does_not_have_model_version_id_and_other_fields(m):
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
"""Validate that model does not have model_version_id and other model fields."""
|
12
|
+
if ('model_version_id' in m) and _model_has_other_fields(m):
|
13
|
+
raise SchemaError(
|
14
|
+
f"model should not set model_version_id and other model fields: {m};"
|
15
|
+
f" please remove model_version_id or other model fields."
|
16
|
+
)
|
17
|
+
return True
|
16
18
|
|
17
19
|
|
18
20
|
def _model_has_other_fields(m):
|
19
|
-
|
21
|
+
return any(k not in ['model_id', 'model_version_id', 'user_id', 'app_id'] for k in m.keys())
|
20
22
|
|
21
23
|
|
22
24
|
def _workflow_nodes_have_valid_dependencies(nodes):
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
"""Validate that all inputs to a node are declared before it."""
|
26
|
+
node_ids = set()
|
27
|
+
for node in nodes:
|
28
|
+
for node_input in node.get("node_inputs", []):
|
29
|
+
if node_input["node_id"] not in node_ids:
|
30
|
+
raise SchemaError(
|
31
|
+
f"missing input '{node_input['node_id']}' for node '{node['id']}'"
|
32
|
+
)
|
33
|
+
node_ids.add(node["id"])
|
30
34
|
|
31
|
-
|
35
|
+
return True
|
32
36
|
|
33
37
|
|
34
|
-
_data_schema = Schema(
|
35
|
-
|
36
|
-
"
|
37
|
-
_id_validator,
|
38
|
-
|
39
|
-
And(
|
38
|
+
_data_schema = Schema(
|
39
|
+
{
|
40
|
+
"workflow": {
|
41
|
+
"id": _id_validator,
|
42
|
+
"nodes": And(
|
40
43
|
len,
|
41
|
-
[
|
42
|
-
|
43
|
-
And(str, len), # Node IDs are not validated as IDs by the API.
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
44
|
+
[
|
45
|
+
{
|
46
|
+
"id": And(str, len), # Node IDs are not validated as IDs by the API.
|
47
|
+
"model": And(
|
48
|
+
{
|
49
|
+
"model_id": _id_validator,
|
50
|
+
Optional("app_id"): _id_validator,
|
51
|
+
Optional("user_id"): _id_validator,
|
52
|
+
Optional("model_version_id"): _hex_id_validator,
|
53
|
+
Optional("model_type_id"): _id_validator,
|
54
|
+
Optional("description"): str,
|
55
|
+
Optional("output_info"): {
|
56
|
+
Optional("params"): dict,
|
57
|
+
},
|
54
58
|
},
|
55
|
-
|
56
|
-
|
57
|
-
And(
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
_model_does_not_have_model_version_id_and_other_fields,
|
60
|
+
),
|
61
|
+
Optional("node_inputs"): And(
|
62
|
+
len,
|
63
|
+
[
|
64
|
+
{
|
65
|
+
"node_id": And(str, len),
|
66
|
+
}
|
67
|
+
],
|
68
|
+
),
|
69
|
+
}
|
70
|
+
],
|
71
|
+
_workflow_nodes_have_valid_dependencies,
|
72
|
+
),
|
73
|
+
},
|
74
|
+
}
|
75
|
+
)
|
64
76
|
|
65
77
|
|
66
78
|
def validate(data):
|
67
|
-
|
79
|
+
return _data_schema.validate(data)
|
@@ -1,7 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: clarifai
|
3
|
-
Version: 11.
|
4
|
-
Summary: Clarifai Python SDK
|
3
|
+
Version: 11.4.0
|
5
4
|
Home-page: https://github.com/Clarifai/clarifai-python
|
6
5
|
Author: Clarifai
|
7
6
|
Author-email: support@clarifai.com
|
@@ -20,8 +19,8 @@ Classifier: Operating System :: OS Independent
|
|
20
19
|
Requires-Python: >=3.8
|
21
20
|
Description-Content-Type: text/markdown
|
22
21
|
License-File: LICENSE
|
23
|
-
Requires-Dist: clarifai-grpc>=11.3.
|
24
|
-
Requires-Dist: clarifai-protocol>=0.0.
|
22
|
+
Requires-Dist: clarifai-grpc>=11.3.4
|
23
|
+
Requires-Dist: clarifai-protocol>=0.0.23
|
25
24
|
Requires-Dist: numpy>=1.22.0
|
26
25
|
Requires-Dist: tqdm>=4.65.0
|
27
26
|
Requires-Dist: rich>=13.4.2
|
@@ -34,7 +33,18 @@ Requires-Dist: click>=8.1.7
|
|
34
33
|
Requires-Dist: requests>=2.32.3
|
35
34
|
Requires-Dist: aiohttp>=3.10.0
|
36
35
|
Provides-Extra: all
|
37
|
-
Requires-Dist: pycocotools
|
36
|
+
Requires-Dist: pycocotools>=2.0.7; extra == "all"
|
37
|
+
Dynamic: author
|
38
|
+
Dynamic: author-email
|
39
|
+
Dynamic: classifier
|
40
|
+
Dynamic: description
|
41
|
+
Dynamic: description-content-type
|
42
|
+
Dynamic: home-page
|
43
|
+
Dynamic: license
|
44
|
+
Dynamic: license-file
|
45
|
+
Dynamic: provides-extra
|
46
|
+
Dynamic: requires-dist
|
47
|
+
Dynamic: requires-python
|
38
48
|
|
39
49
|
<h1 align="center">
|
40
50
|
<a href="https://www.clarifai.com/"><img alt="Clarifai" title="Clarifai" src="https://github.com/user-attachments/assets/623b883b-7fe5-4b95-bbfa-8691f5779af4"></a>
|