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/client/app.py
CHANGED
@@ -26,915 +26,977 @@ from clarifai.workflows.validate import validate
|
|
26
26
|
|
27
27
|
|
28
28
|
class App(Lister, BaseClient):
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
29
|
+
"""App is a class that provides access to Clarifai API endpoints related to App information."""
|
30
|
+
|
31
|
+
def __init__(
|
32
|
+
self,
|
33
|
+
url: str = None,
|
34
|
+
app_id: str = None,
|
35
|
+
user_id: str = None,
|
36
|
+
base_url: str = "https://api.clarifai.com",
|
37
|
+
pat: str = None,
|
38
|
+
token: str = None,
|
39
|
+
root_certificates_path: str = None,
|
40
|
+
**kwargs,
|
41
|
+
):
|
42
|
+
"""Initializes an App object.
|
43
|
+
|
44
|
+
Args:
|
45
|
+
url (str): The URL to initialize the app object.
|
46
|
+
app_id (str): The App ID for the App to interact with.
|
47
|
+
base_url (str): Base API url. Default "https://api.clarifai.com"
|
48
|
+
pat (str): A personal access token for authentication. Can be set as env var CLARIFAI_PAT
|
49
|
+
token (str): A session token for authentication. Accepts either a session token or a pat. Can be set as env var CLARIFAI_SESSION_TOKEN
|
50
|
+
root_certificates_path (str): Path to the SSL root certificates file, used to establish secure gRPC connections.
|
51
|
+
**kwargs: Additional keyword arguments to be passed to the App.
|
52
|
+
- name (str): The name of the app.
|
53
|
+
- description (str): The description of the app.
|
54
|
+
"""
|
55
|
+
if url and app_id:
|
56
|
+
raise UserError("You can only specify one of url or app_id.")
|
57
|
+
if url:
|
58
|
+
user_id, app_id = ClarifaiUrlHelper.split_clarifai_app_url(url)
|
59
|
+
kwargs = {'user_id': user_id}
|
60
|
+
if user_id:
|
61
|
+
kwargs = {'user_id': user_id}
|
62
|
+
|
63
|
+
self.kwargs = {**kwargs, 'id': app_id}
|
64
|
+
self.app_info = resources_pb2.App(**self.kwargs)
|
65
|
+
self.logger = logger
|
66
|
+
BaseClient.__init__(
|
67
|
+
self,
|
68
|
+
user_id=self.user_id,
|
69
|
+
app_id=self.id,
|
70
|
+
base=base_url,
|
71
|
+
pat=pat,
|
72
|
+
token=token,
|
73
|
+
root_certificates_path=root_certificates_path,
|
74
|
+
)
|
75
|
+
Lister.__init__(self)
|
76
|
+
|
77
|
+
def list_datasets(
|
78
|
+
self, page_no: int = None, per_page: int = None
|
79
|
+
) -> Generator[Dataset, None, None]:
|
80
|
+
"""Lists all the datasets for the app.
|
81
|
+
|
82
|
+
Args:
|
83
|
+
page_no (int): The page number to list.
|
84
|
+
per_page (int): The number of items per page.
|
85
|
+
|
86
|
+
Yields:
|
87
|
+
Dataset: Dataset objects for the datasets in the app.
|
88
|
+
|
89
|
+
Example:
|
90
|
+
>>> from clarifai.client.app import App
|
91
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
92
|
+
>>> all_datasets = list(app.list_datasets())
|
93
|
+
|
94
|
+
Note:
|
95
|
+
Defaults to 16 per page if page_no is specified and per_page is not specified.
|
96
|
+
If both page_no and per_page are None, then lists all the resources.
|
97
|
+
"""
|
98
|
+
request_data = dict(
|
99
|
+
user_app_id=self.user_app_id,
|
100
|
+
)
|
101
|
+
all_datasets_info = self.list_pages_generator(
|
102
|
+
self.STUB.ListDatasets,
|
103
|
+
service_pb2.ListDatasetsRequest,
|
104
|
+
request_data,
|
105
|
+
per_page=per_page,
|
106
|
+
page_no=page_no,
|
107
|
+
)
|
108
|
+
for dataset_info in all_datasets_info:
|
109
|
+
if 'version' in dataset_info:
|
110
|
+
dataset_info['version'].pop('metrics', None)
|
111
|
+
dataset_info['version'].pop('export_info', None)
|
112
|
+
yield Dataset.from_auth_helper(auth=self.auth_helper, **dataset_info)
|
113
|
+
|
114
|
+
def list_models(
|
115
|
+
self,
|
116
|
+
filter_by: Dict[str, Any] = {},
|
117
|
+
only_in_app: bool = True,
|
118
|
+
page_no: int = None,
|
119
|
+
per_page: int = None,
|
120
|
+
) -> Generator[Model, None, None]:
|
121
|
+
"""Lists all the available models for the user.
|
122
|
+
|
123
|
+
Args:
|
124
|
+
filter_by (dict): A dictionary of filters to apply to the list of models.
|
125
|
+
only_in_app (bool): If True, only return models that are in the app.
|
126
|
+
page_no (int): The page number to list.
|
127
|
+
per_page (int): The number of items per page.
|
128
|
+
|
129
|
+
Yields:
|
130
|
+
Model: Model objects for the models in the app.
|
131
|
+
|
132
|
+
Example:
|
133
|
+
>>> from clarifai.client.user import User
|
134
|
+
>>> app = User(user_id="user_id").app(app_id="app_id")
|
135
|
+
>>> all_models = list(app.list_models())
|
136
|
+
|
137
|
+
Note:
|
138
|
+
Defaults to 16 per page if page_no is specified and per_page is not specified.
|
139
|
+
If both page_no and per_page are None, then lists all the resources.
|
140
|
+
"""
|
141
|
+
request_data = dict(user_app_id=self.user_app_id, **filter_by)
|
142
|
+
all_models_info = self.list_pages_generator(
|
143
|
+
self.STUB.ListModels,
|
144
|
+
service_pb2.ListModelsRequest,
|
145
|
+
request_data,
|
146
|
+
per_page=per_page,
|
147
|
+
page_no=page_no,
|
148
|
+
)
|
149
|
+
|
150
|
+
for model_info in all_models_info:
|
151
|
+
if 'model_version' not in list(model_info.keys()):
|
152
|
+
continue
|
153
|
+
if only_in_app:
|
154
|
+
if model_info['app_id'] != self.id:
|
155
|
+
continue
|
156
|
+
yield Model.from_auth_helper(auth=self.auth_helper, **model_info)
|
157
|
+
|
158
|
+
def list_workflows(
|
159
|
+
self,
|
160
|
+
filter_by: Dict[str, Any] = {},
|
161
|
+
only_in_app: bool = True,
|
162
|
+
page_no: int = None,
|
163
|
+
per_page: int = None,
|
164
|
+
) -> Generator[Workflow, None, None]:
|
165
|
+
"""Lists all the available workflows for the user.
|
166
|
+
|
167
|
+
Args:
|
168
|
+
filter_by (dict): A dictionary of filters to apply to the list of workflows.
|
169
|
+
only_in_app (bool): If True, only return workflows that are in the app.
|
170
|
+
page_no (int): The page number to list.
|
171
|
+
per_page (int): The number of items per page.
|
172
|
+
|
173
|
+
Yields:
|
174
|
+
Workflow: Workflow objects for the workflows in the app.
|
175
|
+
|
176
|
+
Example:
|
177
|
+
>>> from clarifai.client.app import App
|
178
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
179
|
+
>>> all_workflows = list(app.list_workflows())
|
180
|
+
|
181
|
+
Note:
|
182
|
+
Defaults to 16 per page if page_no is specified and per_page is not specified.
|
183
|
+
If both page_no and per_page are None, then lists all the resources.
|
184
|
+
"""
|
185
|
+
request_data = dict(user_app_id=self.user_app_id, **filter_by)
|
186
|
+
all_workflows_info = self.list_pages_generator(
|
187
|
+
self.STUB.ListWorkflows,
|
188
|
+
service_pb2.ListWorkflowsRequest,
|
189
|
+
request_data,
|
190
|
+
per_page=per_page,
|
191
|
+
page_no=page_no,
|
192
|
+
)
|
193
|
+
|
194
|
+
for workflow_info in all_workflows_info:
|
195
|
+
if only_in_app:
|
196
|
+
if workflow_info['app_id'] != self.id:
|
197
|
+
continue
|
198
|
+
yield Workflow.from_auth_helper(auth=self.auth_helper, **workflow_info)
|
199
|
+
|
200
|
+
def list_modules(
|
201
|
+
self,
|
202
|
+
filter_by: Dict[str, Any] = {},
|
203
|
+
only_in_app: bool = True,
|
204
|
+
page_no: int = None,
|
205
|
+
per_page: int = None,
|
206
|
+
) -> Generator[Module, None, None]:
|
207
|
+
"""Lists all the available modules for the user.
|
208
|
+
|
209
|
+
Args:
|
210
|
+
filter_by (dict): A dictionary of filters to apply to the list of modules.
|
211
|
+
only_in_app (bool): If True, only return modules that are in the app.
|
212
|
+
page_no (int): The page number to list.
|
213
|
+
per_page (int): The number of items per page.
|
214
|
+
|
215
|
+
Yields:
|
216
|
+
Module: Module objects for the modules in the app.
|
217
|
+
|
218
|
+
Example:
|
219
|
+
>>> from clarifai.client.app import App
|
220
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
221
|
+
>>> all_modules = list(app.list_modules())
|
222
|
+
|
223
|
+
Note:
|
224
|
+
Defaults to 16 per page if page_no is specified and per_page is not specified.
|
225
|
+
If both page_no and per_page are None, then lists all the resources.
|
226
|
+
"""
|
227
|
+
request_data = dict(user_app_id=self.user_app_id, **filter_by)
|
228
|
+
all_modules_info = self.list_pages_generator(
|
229
|
+
self.STUB.ListModules,
|
230
|
+
service_pb2.ListModulesRequest,
|
231
|
+
request_data,
|
232
|
+
per_page=per_page,
|
233
|
+
page_no=page_no,
|
234
|
+
)
|
235
|
+
|
236
|
+
for module_info in all_modules_info:
|
237
|
+
if only_in_app:
|
238
|
+
if module_info['app_id'] != self.id:
|
239
|
+
continue
|
240
|
+
yield Module.from_auth_helper(auth=self.auth_helper, **module_info)
|
241
|
+
|
242
|
+
def list_installed_module_versions(
|
243
|
+
self, filter_by: Dict[str, Any] = {}, page_no: int = None, per_page: int = None
|
244
|
+
) -> Generator[Module, None, None]:
|
245
|
+
"""Lists all installed module versions in the app.
|
246
|
+
|
247
|
+
Args:
|
248
|
+
filter_by (dict): A dictionary of filters to apply to the list of installed module versions.
|
249
|
+
page_no (int): The page number to list.
|
250
|
+
per_page (int): The number of items per page.
|
251
|
+
|
252
|
+
Yields:
|
253
|
+
Module: Module objects for the installed module versions in the app.
|
254
|
+
|
255
|
+
Example:
|
256
|
+
>>> from clarifai.client.app import App
|
257
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
258
|
+
>>> all_installed_module_versions = list(app.list_installed_module_versions())
|
259
|
+
|
260
|
+
Note:
|
261
|
+
Defaults to 16 per page if page_no is specified and per_page is not specified.
|
262
|
+
If both page_no and per_page are None, then lists all the resources.
|
263
|
+
"""
|
264
|
+
request_data = dict(user_app_id=self.user_app_id, **filter_by)
|
265
|
+
all_imv_infos = self.list_pages_generator(
|
266
|
+
self.STUB.ListInstalledModuleVersions,
|
267
|
+
service_pb2.ListInstalledModuleVersionsRequest,
|
268
|
+
request_data,
|
269
|
+
per_page=per_page,
|
270
|
+
page_no=page_no,
|
271
|
+
)
|
272
|
+
for imv_info in all_imv_infos:
|
273
|
+
del imv_info['deploy_url']
|
274
|
+
del imv_info['installed_module_version_id'] # TODO: remove this after the backend fix
|
275
|
+
yield Module.from_auth_helper(
|
276
|
+
auth=self.auth_helper,
|
277
|
+
module_id=imv_info['module_version']['module_id'],
|
278
|
+
**imv_info,
|
279
|
+
)
|
280
|
+
|
281
|
+
def get_input_count(self) -> int:
|
282
|
+
"""Get count of all the inputs in the app.
|
283
|
+
|
284
|
+
Returns:
|
285
|
+
input_count: count of inputs in the app.
|
286
|
+
|
287
|
+
Example:
|
288
|
+
>>> from clarifai.client.app import App
|
289
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
290
|
+
>>> input_count = app.get_input_count()
|
291
|
+
"""
|
292
|
+
request = service_pb2.GetInputCountRequest(user_app_id=self.user_app_id)
|
293
|
+
response = self._grpc_request(self.STUB.GetInputCount, request)
|
294
|
+
|
295
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
296
|
+
raise Exception(response.status)
|
297
|
+
self.logger.info("\nGetting App input Counts\n%s", response.status)
|
298
|
+
|
299
|
+
return response.counts.processed
|
300
|
+
|
301
|
+
def list_concepts(
|
302
|
+
self, page_no: int = None, per_page: int = None
|
303
|
+
) -> Generator[Concept, None, None]:
|
304
|
+
"""Lists all the concepts for the app.
|
305
|
+
Args:
|
306
|
+
page_no (int): The page number to list.
|
307
|
+
per_page (int): The number of items per page.
|
308
|
+
|
309
|
+
Yields:
|
310
|
+
Concept: Concepts in the app.
|
311
|
+
|
312
|
+
Example:
|
313
|
+
>>> from clarifai.client.app import App
|
314
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
315
|
+
>>> all_concepts = list(app.list_concepts())
|
316
|
+
|
317
|
+
Note:
|
318
|
+
Defaults to 16 per page if page_no is specified and per_page is not specified.
|
319
|
+
If both page_no and per_page are None, then lists all the resources.
|
320
|
+
"""
|
321
|
+
request_data = dict(user_app_id=self.user_app_id)
|
322
|
+
all_concepts_infos = self.list_pages_generator(
|
323
|
+
self.STUB.ListConcepts,
|
324
|
+
service_pb2.ListConceptsRequest,
|
325
|
+
request_data,
|
326
|
+
per_page=per_page,
|
327
|
+
page_no=page_no,
|
328
|
+
)
|
329
|
+
for concept_info in all_concepts_infos:
|
330
|
+
concept_info['id'] = concept_info.pop('concept_id')
|
331
|
+
yield Concept(**concept_info)
|
332
|
+
|
333
|
+
def search_concept_relations(
|
334
|
+
self,
|
335
|
+
concept_id: str = None,
|
336
|
+
predicate: str = None,
|
337
|
+
page_no: int = None,
|
338
|
+
per_page: int = None,
|
339
|
+
show_tree: bool = False,
|
340
|
+
) -> Generator[ConceptRelation, None, None]:
|
341
|
+
"""List all the concept relations of the app.
|
342
|
+
|
343
|
+
Args:
|
344
|
+
concept_id (str, optional): The concept ID to filter the concept relations.
|
345
|
+
predicate (str, optional): Type of relation to filter the concept relations. For ex : 'hypernym', 'hyponym' or 'synonym'
|
346
|
+
page_no (int, optional): The page number to list.
|
347
|
+
per_page (int, optional): The number of items per page.
|
348
|
+
show_tree (bool, optional): If True, prints out rich tree representation of concept relations.
|
349
|
+
|
350
|
+
Yields:
|
351
|
+
ConceptRelation: ConceptRelations in the app.
|
352
|
+
|
353
|
+
Example:
|
354
|
+
>>> from clarifai.client.app import App
|
355
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
356
|
+
>>> all_concept_relations = list(app.search_concept_relations())
|
357
|
+
|
358
|
+
Note:
|
359
|
+
Defaults to 16 per page if page_no is specified and per_page is not specified.
|
360
|
+
If both page_no and per_page are None, then lists all the resources.
|
361
|
+
"""
|
362
|
+
request_data = dict(
|
363
|
+
user_app_id=self.user_app_id, concept_id=concept_id, predicate=predicate
|
364
|
+
)
|
365
|
+
all_concept_relations_infos = self.list_pages_generator(
|
366
|
+
self.STUB.ListConceptRelations,
|
367
|
+
service_pb2.ListConceptRelationsRequest,
|
368
|
+
request_data,
|
369
|
+
per_page=per_page,
|
370
|
+
page_no=page_no,
|
371
|
+
)
|
372
|
+
relations_dict = {}
|
373
|
+
for concept_relation_info in all_concept_relations_infos:
|
374
|
+
if show_tree:
|
375
|
+
current_subject_concept = concept_relation_info['subject_concept']['id']
|
376
|
+
current_object_concept = concept_relation_info['object_concept']['id']
|
377
|
+
current_predicate = concept_relation_info['predicate']
|
378
|
+
relations_dict = concept_relations_accumulation(
|
379
|
+
relations_dict,
|
380
|
+
current_subject_concept,
|
381
|
+
current_object_concept,
|
382
|
+
current_predicate,
|
383
|
+
)
|
384
|
+
concept_relation_info['id'] = concept_relation_info.pop('concept_relation_id')
|
385
|
+
yield ConceptRelation(**concept_relation_info)
|
386
|
+
if show_tree:
|
387
|
+
display_concept_relations_tree(relations_dict)
|
388
|
+
|
389
|
+
def list_trainable_model_types(self) -> List[str]:
|
390
|
+
"""Lists all the trainable model types.
|
391
|
+
|
392
|
+
Returns:
|
393
|
+
templates (List): List all the trainable model types.
|
394
|
+
|
395
|
+
Example:
|
396
|
+
>>> from clarifai.client.app import App
|
397
|
+
>>> print(app.list_trainable_model_types())
|
398
|
+
"""
|
399
|
+
return TRAINABLE_MODEL_TYPES
|
400
|
+
|
401
|
+
def create_dataset(self, dataset_id: str, **kwargs) -> Dataset:
|
402
|
+
"""Creates a dataset for the app.
|
403
|
+
|
404
|
+
Args:
|
405
|
+
dataset_id (str): The dataset ID for the dataset to create.
|
406
|
+
**kwargs: Additional keyword arguments to be passed to the Dataset.
|
407
|
+
|
408
|
+
Returns:
|
409
|
+
Dataset: A Dataset object for the specified dataset ID.
|
410
|
+
|
411
|
+
Example:
|
412
|
+
>>> from clarifai.client.app import App
|
413
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
414
|
+
>>> dataset = app.create_dataset(dataset_id="dataset_id")
|
415
|
+
"""
|
416
|
+
request = service_pb2.PostDatasetsRequest(
|
417
|
+
user_app_id=self.user_app_id, datasets=[resources_pb2.Dataset(id=dataset_id, **kwargs)]
|
418
|
+
)
|
419
|
+
response = self._grpc_request(self.STUB.PostDatasets, request)
|
420
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
421
|
+
raise Exception(response.status)
|
422
|
+
self.logger.info("\nDataset created\n%s", response.status)
|
423
|
+
|
424
|
+
return Dataset.from_auth_helper(self.auth_helper, dataset_id=dataset_id, **kwargs)
|
425
|
+
|
426
|
+
def create_model(self, model_id: str, **kwargs) -> Model:
|
427
|
+
"""Creates a model for the app.
|
428
|
+
|
429
|
+
Args:
|
430
|
+
model_id (str): The model ID for the model to create.
|
431
|
+
**kwargs: Additional keyword arguments to be passed to the Model.
|
432
|
+
|
433
|
+
Returns:
|
434
|
+
Model: A Model object for the specified model ID.
|
435
|
+
|
436
|
+
Example:
|
437
|
+
>>> from clarifai.client.app import App
|
438
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
439
|
+
>>> model = app.create_model(model_id="model_id")
|
440
|
+
"""
|
441
|
+
request = service_pb2.PostModelsRequest(
|
442
|
+
user_app_id=self.user_app_id, models=[resources_pb2.Model(id=model_id, **kwargs)]
|
443
|
+
)
|
444
|
+
response = self._grpc_request(self.STUB.PostModels, request)
|
445
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
446
|
+
raise Exception(response.status)
|
447
|
+
self.logger.info("\nModel created\n%s", response.status)
|
448
|
+
kwargs.update(
|
449
|
+
{
|
450
|
+
'model_id': model_id,
|
451
|
+
'model_type_id': response.model.model_type_id,
|
452
|
+
}
|
453
|
+
)
|
454
|
+
|
455
|
+
return Model.from_auth_helper(auth=self.auth_helper, **kwargs)
|
456
|
+
|
457
|
+
def _process_workflow_config(self, config_filepath: str):
|
458
|
+
with open(config_filepath, 'r') as file:
|
459
|
+
workflow_config = yaml.safe_load(file)
|
460
|
+
|
461
|
+
workflow_config = validate(workflow_config)
|
462
|
+
workflow = workflow_config['workflow']
|
463
|
+
|
464
|
+
# Get all model objects from the workflow nodes.
|
465
|
+
all_models = []
|
466
|
+
for node in workflow['nodes']:
|
467
|
+
output_info = get_yaml_output_info_proto(node['model'].get('output_info', None))
|
468
|
+
try:
|
469
|
+
model = self.model(
|
470
|
+
model_id=node['model']['model_id'],
|
471
|
+
model_version={"id": node['model'].get('model_version_id', "")},
|
472
|
+
user_id=node['model'].get('user_id', ""),
|
473
|
+
app_id=node['model'].get('app_id', ""),
|
474
|
+
)
|
475
|
+
except Exception as e:
|
476
|
+
if "Model does not exist" in str(e):
|
477
|
+
model = self.create_model(
|
478
|
+
**{k: v for k, v in node['model'].items() if k != 'output_info'}
|
479
|
+
)
|
480
|
+
model_version = model.create_version(output_info=output_info)
|
481
|
+
all_models.append(model_version.model_info)
|
482
|
+
continue
|
483
|
+
|
484
|
+
# If the model version ID is specified, or if the yaml model is the same as the one in the api
|
485
|
+
if node["model"].get("model_version_id", "") or is_same_yaml_model(
|
486
|
+
model.model_info, node["model"]
|
487
|
+
):
|
488
|
+
all_models.append(model.model_info)
|
489
|
+
else: # Create a new model version
|
490
|
+
model = model.create_version(output_info=output_info)
|
491
|
+
all_models.append(model.model_info)
|
492
|
+
|
493
|
+
# Convert nodes to resources_pb2.WorkflowNodes.
|
494
|
+
nodes = []
|
495
|
+
for i, yml_node in enumerate(workflow['nodes']):
|
496
|
+
node = resources_pb2.WorkflowNode(
|
497
|
+
id=yml_node['id'],
|
498
|
+
model=all_models[i],
|
499
|
+
)
|
500
|
+
# Add node inputs if they exist, i.e. if these nodes do not connect directly to the input.
|
501
|
+
if yml_node.get("node_inputs"):
|
502
|
+
for ni in yml_node.get("node_inputs"):
|
503
|
+
node.node_inputs.append(resources_pb2.NodeInput(node_id=ni['node_id']))
|
504
|
+
nodes.append(node)
|
505
|
+
|
506
|
+
return workflow, nodes
|
507
|
+
|
508
|
+
def create_workflow(
|
509
|
+
self, config_filepath: str, generate_new_id: bool = False, display: bool = True
|
510
|
+
) -> Workflow:
|
511
|
+
"""Creates a workflow for the app.
|
512
|
+
|
513
|
+
Args:
|
514
|
+
config_filepath (str): The path to the yaml workflow config file.
|
515
|
+
generate_new_id (bool): If True, generate a new workflow ID.
|
516
|
+
display (bool): If True, display the workflow nodes tree.
|
517
|
+
|
518
|
+
Returns:
|
519
|
+
Workflow: A Workflow object for the specified workflow config.
|
520
|
+
|
521
|
+
Example:
|
522
|
+
>>> from clarifai.client.app import App
|
523
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
524
|
+
>>> workflow = app.create_workflow(config_filepath="config.yml")
|
525
|
+
"""
|
526
|
+
if not os.path.exists(config_filepath):
|
527
|
+
raise UserError(f"Workflow config file not found at {config_filepath}")
|
528
|
+
|
529
|
+
workflow, nodes = self._process_workflow_config(config_filepath)
|
530
|
+
|
531
|
+
workflow_id = workflow['id']
|
532
|
+
if generate_new_id:
|
533
|
+
workflow_id = str(uuid.uuid4())
|
534
|
+
|
535
|
+
# Create the workflow.
|
536
|
+
request = service_pb2.PostWorkflowsRequest(
|
537
|
+
user_app_id=self.user_app_id,
|
538
|
+
workflows=[resources_pb2.Workflow(id=workflow_id, nodes=nodes)],
|
539
|
+
)
|
540
|
+
|
541
|
+
response = self._grpc_request(self.STUB.PostWorkflows, request)
|
542
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
543
|
+
raise Exception(response.status)
|
544
|
+
self.logger.info("\nWorkflow created\n%s", response.status)
|
545
|
+
|
546
|
+
dict_response = MessageToDict(response, preserving_proto_field_name=True)
|
547
|
+
# Display the workflow nodes tree.
|
548
|
+
wf = dict_response["workflows"][0]
|
549
|
+
if display:
|
550
|
+
display_workflow_tree(wf["nodes"])
|
551
|
+
kwargs = self.process_response_keys(wf, "workflow")
|
552
|
+
|
553
|
+
return Workflow.from_auth_helper(auth=self.auth_helper, **kwargs)
|
554
|
+
|
555
|
+
def create_module(self, module_id: str, description: str, **kwargs) -> Module:
|
556
|
+
"""Creates a module for the app.
|
557
|
+
|
558
|
+
Args:
|
559
|
+
module_id (str): The module ID for the module to create.
|
560
|
+
description (str): The description of the module to create.
|
561
|
+
**kwargs: Additional keyword arguments to be passed to the module.
|
562
|
+
|
563
|
+
Returns:
|
564
|
+
Module: A Module object for the specified module ID.
|
565
|
+
|
566
|
+
Example:
|
567
|
+
>>> from clarifai.client.app import App
|
568
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
569
|
+
>>> module = app.create_module(module_id="module_id")
|
570
|
+
"""
|
571
|
+
request = service_pb2.PostModulesRequest(
|
572
|
+
user_app_id=self.user_app_id,
|
573
|
+
modules=[resources_pb2.Module(id=module_id, description=description, **kwargs)],
|
574
|
+
)
|
575
|
+
response = self._grpc_request(self.STUB.PostModules, request)
|
576
|
+
|
577
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
578
|
+
raise Exception(response.status)
|
579
|
+
self.logger.info("\nModule created\n%s", response.status)
|
580
|
+
|
581
|
+
return Module.from_auth_helper(auth=self.auth_helper, module_id=module_id, **kwargs)
|
582
|
+
|
583
|
+
def create_concepts(self, concept_ids: List[str], concepts: List[str] = []) -> None:
|
584
|
+
"""Add concepts to the app.
|
585
|
+
|
586
|
+
Args:
|
587
|
+
concept_ids (List[str]): List of concept IDs of concepts to add to the app.
|
588
|
+
concepts (List[str], optional): List of concepts names of concepts to add to the app.
|
589
|
+
|
590
|
+
Example:
|
591
|
+
>>> from clarifai.client.app import App
|
592
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
593
|
+
>>> app.add_concepts(concept_ids=["concept_id_1", "concept_id_2", ..])
|
594
|
+
"""
|
595
|
+
if not concepts:
|
596
|
+
concepts = list(concept_ids)
|
597
|
+
concepts_to_add = [
|
598
|
+
resources_pb2.Concept(id=concept_id, name=concept)
|
599
|
+
for concept_id, concept in zip(concept_ids, concepts)
|
600
|
+
]
|
601
|
+
request = service_pb2.PostConceptsRequest(
|
602
|
+
user_app_id=self.user_app_id, concepts=concepts_to_add
|
603
|
+
)
|
604
|
+
response = self._grpc_request(self.STUB.PostConcepts, request)
|
605
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
606
|
+
raise Exception(response.status)
|
607
|
+
self.logger.info("\nConcepts added\n%s", response.status)
|
608
|
+
|
609
|
+
def create_concept_relations(
|
610
|
+
self, subject_concept_id: str, object_concept_ids: List[str], predicates: List[str]
|
611
|
+
) -> None:
|
612
|
+
"""Creates concept relations between concepts of the app.
|
613
|
+
|
614
|
+
Args:
|
615
|
+
subject_concept_id (str): The concept ID of the subject concept.
|
616
|
+
object_concept_ids (List[str]): List of concepts IDs of object concepts.
|
617
|
+
predicates (List[str]): List of predicates corresponding to each relation between subject and objects.
|
618
|
+
|
619
|
+
Example:
|
620
|
+
>>> from clarifai.client.app import App
|
621
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
622
|
+
>>> app.create_concept_relation(subject_concept_id="subject_concept_id", object_concept_ids=["object_concept_id_1", "object_concept_id_2", ..], predicates=["predicate_1", "predicate_2", ..])
|
623
|
+
"""
|
624
|
+
assert len(object_concept_ids) == len(predicates)
|
625
|
+
subject_relations = [
|
626
|
+
resources_pb2.ConceptRelation(
|
627
|
+
object_concept=resources_pb2.Concept(id=object_concept_id), predicate=predicate
|
628
|
+
)
|
629
|
+
for object_concept_id, predicate in zip(object_concept_ids, predicates)
|
630
|
+
]
|
631
|
+
request = service_pb2.PostConceptRelationsRequest(
|
632
|
+
user_app_id=self.user_app_id,
|
633
|
+
concept_id=subject_concept_id,
|
634
|
+
concept_relations=subject_relations,
|
635
|
+
)
|
636
|
+
response = self._grpc_request(self.STUB.PostConceptRelations, request)
|
637
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
638
|
+
raise Exception(response.status)
|
639
|
+
self.logger.info("\nConcept Relations created\n%s", response.status)
|
640
|
+
|
641
|
+
def dataset(self, dataset_id: str, dataset_version_id: str = None, **kwargs) -> Dataset:
|
642
|
+
"""Returns a Dataset object for the existing dataset ID.
|
643
|
+
|
644
|
+
Args:
|
645
|
+
dataset_id (str): The dataset ID for the dataset to interact with.
|
646
|
+
dataset_version_id (str): The version ID for the dataset version to interact with.
|
647
|
+
|
648
|
+
Returns:
|
649
|
+
Dataset: A Dataset object for the existing dataset ID.
|
650
|
+
|
651
|
+
Example:
|
652
|
+
>>> from clarifai.client.app import App
|
653
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
654
|
+
>>> dataset = app.dataset(dataset_id="dataset_id")
|
655
|
+
"""
|
656
|
+
request = service_pb2.GetDatasetRequest(
|
657
|
+
user_app_id=self.user_app_id, dataset_id=dataset_id
|
658
|
+
)
|
659
|
+
response = self._grpc_request(self.STUB.GetDataset, request)
|
660
|
+
|
661
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
662
|
+
raise Exception(response.status)
|
663
|
+
dict_response = MessageToDict(response, preserving_proto_field_name=True)
|
664
|
+
kwargs = self.process_response_keys(dict_response['dataset'], 'dataset')
|
665
|
+
kwargs['version'] = response.dataset.version if response.dataset.version else None
|
666
|
+
kwargs['dataset_version_id'] = dataset_version_id
|
667
|
+
return Dataset.from_auth_helper(auth=self.auth_helper, **kwargs)
|
668
|
+
|
669
|
+
def model(self, model_id: str, model_version: Dict = {'id': ""}, **kwargs) -> Model:
|
670
|
+
"""Returns a Model object for the existing model ID.
|
671
|
+
|
672
|
+
Args:
|
673
|
+
model_id (str): The model ID for the model to interact with.
|
674
|
+
model_version (Dict): The model version ID for the model version to interact with.
|
675
|
+
|
676
|
+
Returns:
|
677
|
+
Model: A Model object for the existing model ID.
|
678
|
+
|
679
|
+
Example:
|
680
|
+
>>> from clarifai.client.app import App
|
681
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
682
|
+
>>> model_v1 = app.model(model_id="model_id", model_version={"id":"model_version_id")
|
683
|
+
"""
|
684
|
+
# Change user_app_id based on whether user_id or app_id is specified.
|
685
|
+
if kwargs.get("user_id") or kwargs.get("app_id"):
|
686
|
+
request = service_pb2.GetModelRequest(
|
687
|
+
user_app_id=self.auth_helper.get_user_app_id_proto(
|
688
|
+
kwargs.get("user_id"), kwargs.get("app_id")
|
689
|
+
),
|
690
|
+
model_id=model_id,
|
691
|
+
version_id=model_version["id"],
|
692
|
+
)
|
693
|
+
else:
|
694
|
+
request = service_pb2.GetModelRequest(
|
695
|
+
user_app_id=self.user_app_id, model_id=model_id, version_id=model_version["id"]
|
696
|
+
)
|
697
|
+
response = self._grpc_request(self.STUB.GetModel, request)
|
698
|
+
|
699
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
700
|
+
raise Exception(response.status)
|
701
|
+
dict_response = MessageToDict(response, preserving_proto_field_name=True)
|
702
|
+
|
703
|
+
kwargs = self.process_response_keys(dict_response['model'], 'model')
|
704
|
+
kwargs['model_version'] = (
|
705
|
+
response.model.model_version if response.model.model_version else None
|
706
|
+
)
|
707
|
+
|
708
|
+
m = Model.from_auth_helper(self.auth_helper, **kwargs)
|
709
|
+
return m
|
710
|
+
|
711
|
+
def workflow(self, workflow_id: str, **kwargs) -> Workflow:
|
712
|
+
"""Returns a workflow object for the existing workflow ID.
|
713
|
+
|
714
|
+
Args:
|
715
|
+
workflow_id (str): The workflow ID for the workflow to interact with.
|
716
|
+
|
717
|
+
Returns:
|
718
|
+
Workflow: A Workflow object for the existing workflow ID.
|
719
|
+
|
720
|
+
Example:
|
721
|
+
>>> from clarifai.client.app import App
|
722
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
723
|
+
>>> workflow = app.workflow(workflow_id="workflow_id")
|
724
|
+
"""
|
725
|
+
request = service_pb2.GetWorkflowRequest(
|
726
|
+
user_app_id=self.user_app_id, workflow_id=workflow_id
|
727
|
+
)
|
728
|
+
response = self._grpc_request(self.STUB.GetWorkflow, request)
|
729
|
+
|
730
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
731
|
+
raise Exception(response.status)
|
732
|
+
dict_response = MessageToDict(response, preserving_proto_field_name=True)
|
733
|
+
kwargs = self.process_response_keys(dict_response['workflow'], "workflow")
|
734
|
+
|
735
|
+
return Workflow.from_auth_helper(auth=self.auth_helper, **kwargs)
|
736
|
+
|
737
|
+
def module(self, module_id: str, **kwargs) -> Module:
|
738
|
+
"""Returns a Module object for the existing module ID.
|
739
|
+
|
740
|
+
Args:
|
741
|
+
module_id (str): The module ID for the module to interact with.
|
742
|
+
module_version_id (str): The module version ID for the module version to interact with.
|
743
|
+
|
744
|
+
Returns:
|
745
|
+
Module: A Module object for the existing module ID.
|
746
|
+
|
747
|
+
Example:
|
748
|
+
>>> from clarifai.client.app import App
|
749
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
750
|
+
>>> module = app.module(module_id="module_id")
|
751
|
+
"""
|
752
|
+
request = service_pb2.GetModuleRequest(user_app_id=self.user_app_id, module_id=module_id)
|
753
|
+
response = self._grpc_request(self.STUB.GetModule, request)
|
754
|
+
|
755
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
756
|
+
raise Exception(response.status)
|
757
|
+
dict_response = MessageToDict(response, preserving_proto_field_name=True)
|
758
|
+
kwargs = self.process_response_keys(dict_response['module'], 'module')
|
759
|
+
|
760
|
+
return Module.from_auth_helper(auth=self.auth_helper, **kwargs)
|
761
|
+
|
762
|
+
def inputs(
|
65
763
|
self,
|
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
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
self
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
request_data,
|
306
|
-
per_page=per_page,
|
307
|
-
page_no=page_no)
|
308
|
-
for concept_info in all_concepts_infos:
|
309
|
-
concept_info['id'] = concept_info.pop('concept_id')
|
310
|
-
yield Concept(**concept_info)
|
311
|
-
|
312
|
-
def search_concept_relations(self,
|
313
|
-
concept_id: str = None,
|
314
|
-
predicate: str = None,
|
315
|
-
page_no: int = None,
|
316
|
-
per_page: int = None,
|
317
|
-
show_tree: bool = False) -> Generator[ConceptRelation, None, None]:
|
318
|
-
"""List all the concept relations of the app.
|
319
|
-
|
320
|
-
Args:
|
321
|
-
concept_id (str, optional): The concept ID to filter the concept relations.
|
322
|
-
predicate (str, optional): Type of relation to filter the concept relations. For ex : 'hypernym', 'hyponym' or 'synonym'
|
323
|
-
page_no (int, optional): The page number to list.
|
324
|
-
per_page (int, optional): The number of items per page.
|
325
|
-
show_tree (bool, optional): If True, prints out rich tree representation of concept relations.
|
326
|
-
|
327
|
-
Yields:
|
328
|
-
ConceptRelation: ConceptRelations in the app.
|
329
|
-
|
330
|
-
Example:
|
331
|
-
>>> from clarifai.client.app import App
|
332
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
333
|
-
>>> all_concept_relations = list(app.search_concept_relations())
|
334
|
-
|
335
|
-
Note:
|
336
|
-
Defaults to 16 per page if page_no is specified and per_page is not specified.
|
337
|
-
If both page_no and per_page are None, then lists all the resources.
|
338
|
-
"""
|
339
|
-
request_data = dict(user_app_id=self.user_app_id, concept_id=concept_id, predicate=predicate)
|
340
|
-
all_concept_relations_infos = self.list_pages_generator(
|
341
|
-
self.STUB.ListConceptRelations,
|
342
|
-
service_pb2.ListConceptRelationsRequest,
|
343
|
-
request_data,
|
344
|
-
per_page=per_page,
|
345
|
-
page_no=page_no)
|
346
|
-
relations_dict = {}
|
347
|
-
for concept_relation_info in all_concept_relations_infos:
|
348
|
-
if show_tree:
|
349
|
-
current_subject_concept = concept_relation_info['subject_concept']['id']
|
350
|
-
current_object_concept = concept_relation_info['object_concept']['id']
|
351
|
-
current_predicate = concept_relation_info['predicate']
|
352
|
-
relations_dict = concept_relations_accumulation(relations_dict, current_subject_concept,
|
353
|
-
current_object_concept, current_predicate)
|
354
|
-
concept_relation_info['id'] = concept_relation_info.pop('concept_relation_id')
|
355
|
-
yield ConceptRelation(**concept_relation_info)
|
356
|
-
if show_tree:
|
357
|
-
display_concept_relations_tree(relations_dict)
|
358
|
-
|
359
|
-
def list_trainable_model_types(self) -> List[str]:
|
360
|
-
"""Lists all the trainable model types.
|
361
|
-
|
362
|
-
Returns:
|
363
|
-
templates (List): List all the trainable model types.
|
364
|
-
|
365
|
-
Example:
|
366
|
-
>>> from clarifai.client.app import App
|
367
|
-
>>> print(app.list_trainable_model_types())
|
368
|
-
"""
|
369
|
-
return TRAINABLE_MODEL_TYPES
|
370
|
-
|
371
|
-
def create_dataset(self, dataset_id: str, **kwargs) -> Dataset:
|
372
|
-
"""Creates a dataset for the app.
|
373
|
-
|
374
|
-
Args:
|
375
|
-
dataset_id (str): The dataset ID for the dataset to create.
|
376
|
-
**kwargs: Additional keyword arguments to be passed to the Dataset.
|
377
|
-
|
378
|
-
Returns:
|
379
|
-
Dataset: A Dataset object for the specified dataset ID.
|
380
|
-
|
381
|
-
Example:
|
382
|
-
>>> from clarifai.client.app import App
|
383
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
384
|
-
>>> dataset = app.create_dataset(dataset_id="dataset_id")
|
385
|
-
"""
|
386
|
-
request = service_pb2.PostDatasetsRequest(
|
387
|
-
user_app_id=self.user_app_id, datasets=[resources_pb2.Dataset(id=dataset_id, **kwargs)])
|
388
|
-
response = self._grpc_request(self.STUB.PostDatasets, request)
|
389
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
390
|
-
raise Exception(response.status)
|
391
|
-
self.logger.info("\nDataset created\n%s", response.status)
|
392
|
-
|
393
|
-
return Dataset.from_auth_helper(self.auth_helper, dataset_id=dataset_id, **kwargs)
|
394
|
-
|
395
|
-
def create_model(self, model_id: str, **kwargs) -> Model:
|
396
|
-
"""Creates a model for the app.
|
397
|
-
|
398
|
-
Args:
|
399
|
-
model_id (str): The model ID for the model to create.
|
400
|
-
**kwargs: Additional keyword arguments to be passed to the Model.
|
401
|
-
|
402
|
-
Returns:
|
403
|
-
Model: A Model object for the specified model ID.
|
404
|
-
|
405
|
-
Example:
|
406
|
-
>>> from clarifai.client.app import App
|
407
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
408
|
-
>>> model = app.create_model(model_id="model_id")
|
409
|
-
"""
|
410
|
-
request = service_pb2.PostModelsRequest(
|
411
|
-
user_app_id=self.user_app_id, models=[resources_pb2.Model(id=model_id, **kwargs)])
|
412
|
-
response = self._grpc_request(self.STUB.PostModels, request)
|
413
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
414
|
-
raise Exception(response.status)
|
415
|
-
self.logger.info("\nModel created\n%s", response.status)
|
416
|
-
kwargs.update({
|
417
|
-
'model_id': model_id,
|
418
|
-
'model_type_id': response.model.model_type_id,
|
419
|
-
})
|
420
|
-
|
421
|
-
return Model.from_auth_helper(auth=self.auth_helper, **kwargs)
|
422
|
-
|
423
|
-
def _process_workflow_config(self, config_filepath: str):
|
424
|
-
with open(config_filepath, 'r') as file:
|
425
|
-
workflow_config = yaml.safe_load(file)
|
426
|
-
|
427
|
-
workflow_config = validate(workflow_config)
|
428
|
-
workflow = workflow_config['workflow']
|
429
|
-
|
430
|
-
# Get all model objects from the workflow nodes.
|
431
|
-
all_models = []
|
432
|
-
for node in workflow['nodes']:
|
433
|
-
output_info = get_yaml_output_info_proto(node['model'].get('output_info', None))
|
434
|
-
try:
|
435
|
-
model = self.model(
|
436
|
-
model_id=node['model']['model_id'],
|
437
|
-
model_version={"id": node['model'].get('model_version_id', "")},
|
438
|
-
user_id=node['model'].get('user_id', ""),
|
439
|
-
app_id=node['model'].get('app_id', ""))
|
440
|
-
except Exception as e:
|
441
|
-
if "Model does not exist" in str(e):
|
442
|
-
model = self.create_model(
|
443
|
-
**{k: v
|
444
|
-
for k, v in node['model'].items() if k != 'output_info'})
|
445
|
-
model_version = model.create_version(output_info=output_info)
|
446
|
-
all_models.append(model_version.model_info)
|
447
|
-
continue
|
448
|
-
|
449
|
-
# If the model version ID is specified, or if the yaml model is the same as the one in the api
|
450
|
-
if node["model"].get("model_version_id", "") or is_same_yaml_model(
|
451
|
-
model.model_info, node["model"]):
|
452
|
-
all_models.append(model.model_info)
|
453
|
-
else: # Create a new model version
|
454
|
-
model = model.create_version(output_info=output_info)
|
455
|
-
all_models.append(model.model_info)
|
456
|
-
|
457
|
-
# Convert nodes to resources_pb2.WorkflowNodes.
|
458
|
-
nodes = []
|
459
|
-
for i, yml_node in enumerate(workflow['nodes']):
|
460
|
-
node = resources_pb2.WorkflowNode(
|
461
|
-
id=yml_node['id'],
|
462
|
-
model=all_models[i],
|
463
|
-
)
|
464
|
-
# Add node inputs if they exist, i.e. if these nodes do not connect directly to the input.
|
465
|
-
if yml_node.get("node_inputs"):
|
466
|
-
for ni in yml_node.get("node_inputs"):
|
467
|
-
node.node_inputs.append(resources_pb2.NodeInput(node_id=ni['node_id']))
|
468
|
-
nodes.append(node)
|
469
|
-
|
470
|
-
return workflow, nodes
|
471
|
-
|
472
|
-
def create_workflow(self,
|
473
|
-
config_filepath: str,
|
474
|
-
generate_new_id: bool = False,
|
475
|
-
display: bool = True) -> Workflow:
|
476
|
-
"""Creates a workflow for the app.
|
477
|
-
|
478
|
-
Args:
|
479
|
-
config_filepath (str): The path to the yaml workflow config file.
|
480
|
-
generate_new_id (bool): If True, generate a new workflow ID.
|
481
|
-
display (bool): If True, display the workflow nodes tree.
|
482
|
-
|
483
|
-
Returns:
|
484
|
-
Workflow: A Workflow object for the specified workflow config.
|
485
|
-
|
486
|
-
Example:
|
487
|
-
>>> from clarifai.client.app import App
|
488
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
489
|
-
>>> workflow = app.create_workflow(config_filepath="config.yml")
|
490
|
-
"""
|
491
|
-
if not os.path.exists(config_filepath):
|
492
|
-
raise UserError(f"Workflow config file not found at {config_filepath}")
|
493
|
-
|
494
|
-
workflow, nodes = self._process_workflow_config(config_filepath)
|
495
|
-
|
496
|
-
workflow_id = workflow['id']
|
497
|
-
if generate_new_id:
|
498
|
-
workflow_id = str(uuid.uuid4())
|
499
|
-
|
500
|
-
# Create the workflow.
|
501
|
-
request = service_pb2.PostWorkflowsRequest(
|
502
|
-
user_app_id=self.user_app_id,
|
503
|
-
workflows=[resources_pb2.Workflow(id=workflow_id, nodes=nodes)])
|
504
|
-
|
505
|
-
response = self._grpc_request(self.STUB.PostWorkflows, request)
|
506
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
507
|
-
raise Exception(response.status)
|
508
|
-
self.logger.info("\nWorkflow created\n%s", response.status)
|
509
|
-
|
510
|
-
dict_response = MessageToDict(response, preserving_proto_field_name=True)
|
511
|
-
# Display the workflow nodes tree.
|
512
|
-
if display:
|
513
|
-
display_workflow_tree(dict_response["workflows"][0]["nodes"])
|
514
|
-
kwargs = self.process_response_keys(dict_response[list(dict_response.keys())[1]][0],
|
515
|
-
"workflow")
|
516
|
-
|
517
|
-
return Workflow.from_auth_helper(auth=self.auth_helper, **kwargs)
|
518
|
-
|
519
|
-
def create_module(self, module_id: str, description: str, **kwargs) -> Module:
|
520
|
-
"""Creates a module for the app.
|
521
|
-
|
522
|
-
Args:
|
523
|
-
module_id (str): The module ID for the module to create.
|
524
|
-
description (str): The description of the module to create.
|
525
|
-
**kwargs: Additional keyword arguments to be passed to the module.
|
526
|
-
|
527
|
-
Returns:
|
528
|
-
Module: A Module object for the specified module ID.
|
529
|
-
|
530
|
-
Example:
|
531
|
-
>>> from clarifai.client.app import App
|
532
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
533
|
-
>>> module = app.create_module(module_id="module_id")
|
534
|
-
"""
|
535
|
-
request = service_pb2.PostModulesRequest(
|
536
|
-
user_app_id=self.user_app_id,
|
537
|
-
modules=[resources_pb2.Module(id=module_id, description=description, **kwargs)])
|
538
|
-
response = self._grpc_request(self.STUB.PostModules, request)
|
539
|
-
|
540
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
541
|
-
raise Exception(response.status)
|
542
|
-
self.logger.info("\nModule created\n%s", response.status)
|
543
|
-
|
544
|
-
return Module.from_auth_helper(auth=self.auth_helper, module_id=module_id, **kwargs)
|
545
|
-
|
546
|
-
def create_concepts(self, concept_ids: List[str], concepts: List[str] = []) -> None:
|
547
|
-
"""Add concepts to the app.
|
548
|
-
|
549
|
-
Args:
|
550
|
-
concept_ids (List[str]): List of concept IDs of concepts to add to the app.
|
551
|
-
concepts (List[str], optional): List of concepts names of concepts to add to the app.
|
552
|
-
|
553
|
-
Example:
|
554
|
-
>>> from clarifai.client.app import App
|
555
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
556
|
-
>>> app.add_concepts(concept_ids=["concept_id_1", "concept_id_2", ..])
|
557
|
-
"""
|
558
|
-
if not concepts:
|
559
|
-
concepts = list(concept_ids)
|
560
|
-
concepts_to_add = [
|
561
|
-
resources_pb2.Concept(id=concept_id, name=concept)
|
562
|
-
for concept_id, concept in zip(concept_ids, concepts)
|
563
|
-
]
|
564
|
-
request = service_pb2.PostConceptsRequest(
|
565
|
-
user_app_id=self.user_app_id, concepts=concepts_to_add)
|
566
|
-
response = self._grpc_request(self.STUB.PostConcepts, request)
|
567
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
568
|
-
raise Exception(response.status)
|
569
|
-
self.logger.info("\nConcepts added\n%s", response.status)
|
570
|
-
|
571
|
-
def create_concept_relations(self, subject_concept_id: str, object_concept_ids: List[str],
|
572
|
-
predicates: List[str]) -> None:
|
573
|
-
"""Creates concept relations between concepts of the app.
|
574
|
-
|
575
|
-
Args:
|
576
|
-
subject_concept_id (str): The concept ID of the subject concept.
|
577
|
-
object_concept_ids (List[str]): List of concepts IDs of object concepts.
|
578
|
-
predicates (List[str]): List of predicates corresponding to each relation between subject and objects.
|
579
|
-
|
580
|
-
Example:
|
581
|
-
>>> from clarifai.client.app import App
|
582
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
583
|
-
>>> app.create_concept_relation(subject_concept_id="subject_concept_id", object_concept_ids=["object_concept_id_1", "object_concept_id_2", ..], predicates=["predicate_1", "predicate_2", ..])
|
584
|
-
"""
|
585
|
-
assert len(object_concept_ids) == len(predicates)
|
586
|
-
subject_relations = [
|
587
|
-
resources_pb2.ConceptRelation(
|
588
|
-
object_concept=resources_pb2.Concept(id=object_concept_id), predicate=predicate)
|
589
|
-
for object_concept_id, predicate in zip(object_concept_ids, predicates)
|
590
|
-
]
|
591
|
-
request = service_pb2.PostConceptRelationsRequest(
|
592
|
-
user_app_id=self.user_app_id,
|
593
|
-
concept_id=subject_concept_id,
|
594
|
-
concept_relations=subject_relations)
|
595
|
-
response = self._grpc_request(self.STUB.PostConceptRelations, request)
|
596
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
597
|
-
raise Exception(response.status)
|
598
|
-
self.logger.info("\nConcept Relations created\n%s", response.status)
|
599
|
-
|
600
|
-
def dataset(self, dataset_id: str, dataset_version_id: str = None, **kwargs) -> Dataset:
|
601
|
-
"""Returns a Dataset object for the existing dataset ID.
|
602
|
-
|
603
|
-
Args:
|
604
|
-
dataset_id (str): The dataset ID for the dataset to interact with.
|
605
|
-
dataset_version_id (str): The version ID for the dataset version to interact with.
|
606
|
-
|
607
|
-
Returns:
|
608
|
-
Dataset: A Dataset object for the existing dataset ID.
|
609
|
-
|
610
|
-
Example:
|
611
|
-
>>> from clarifai.client.app import App
|
612
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
613
|
-
>>> dataset = app.dataset(dataset_id="dataset_id")
|
614
|
-
"""
|
615
|
-
request = service_pb2.GetDatasetRequest(user_app_id=self.user_app_id, dataset_id=dataset_id)
|
616
|
-
response = self._grpc_request(self.STUB.GetDataset, request)
|
617
|
-
|
618
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
619
|
-
raise Exception(response.status)
|
620
|
-
dict_response = MessageToDict(response, preserving_proto_field_name=True)
|
621
|
-
kwargs = self.process_response_keys(dict_response[list(dict_response.keys())[1]],
|
622
|
-
list(dict_response.keys())[1])
|
623
|
-
kwargs['version'] = response.dataset.version if response.dataset.version else None
|
624
|
-
kwargs['dataset_version_id'] = dataset_version_id
|
625
|
-
return Dataset.from_auth_helper(auth=self.auth_helper, **kwargs)
|
626
|
-
|
627
|
-
def model(self, model_id: str, model_version: Dict = {'id': ""}, **kwargs) -> Model:
|
628
|
-
"""Returns a Model object for the existing model ID.
|
629
|
-
|
630
|
-
Args:
|
631
|
-
model_id (str): The model ID for the model to interact with.
|
632
|
-
model_version (Dict): The model version ID for the model version to interact with.
|
633
|
-
|
634
|
-
Returns:
|
635
|
-
Model: A Model object for the existing model ID.
|
636
|
-
|
637
|
-
Example:
|
638
|
-
>>> from clarifai.client.app import App
|
639
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
640
|
-
>>> model_v1 = app.model(model_id="model_id", model_version={"id":"model_version_id")
|
641
|
-
"""
|
642
|
-
# Change user_app_id based on whether user_id or app_id is specified.
|
643
|
-
if kwargs.get("user_id") or kwargs.get("app_id"):
|
644
|
-
request = service_pb2.GetModelRequest(
|
645
|
-
user_app_id=self.auth_helper.get_user_app_id_proto(
|
646
|
-
kwargs.get("user_id"), kwargs.get("app_id")),
|
647
|
-
model_id=model_id,
|
648
|
-
version_id=model_version["id"])
|
649
|
-
else:
|
650
|
-
request = service_pb2.GetModelRequest(
|
651
|
-
user_app_id=self.user_app_id, model_id=model_id, version_id=model_version["id"])
|
652
|
-
response = self._grpc_request(self.STUB.GetModel, request)
|
653
|
-
|
654
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
655
|
-
raise Exception(response.status)
|
656
|
-
dict_response = MessageToDict(response, preserving_proto_field_name=True)
|
657
|
-
kwargs = self.process_response_keys(dict_response['model'], 'model')
|
658
|
-
kwargs[
|
659
|
-
'model_version'] = response.model.model_version if response.model.model_version else None
|
660
|
-
|
661
|
-
return Model.from_auth_helper(self.auth_helper, **kwargs)
|
662
|
-
|
663
|
-
def workflow(self, workflow_id: str, **kwargs) -> Workflow:
|
664
|
-
"""Returns a workflow object for the existing workflow ID.
|
665
|
-
|
666
|
-
Args:
|
667
|
-
workflow_id (str): The workflow ID for the workflow to interact with.
|
668
|
-
|
669
|
-
Returns:
|
670
|
-
Workflow: A Workflow object for the existing workflow ID.
|
671
|
-
|
672
|
-
Example:
|
673
|
-
>>> from clarifai.client.app import App
|
674
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
675
|
-
>>> workflow = app.workflow(workflow_id="workflow_id")
|
676
|
-
"""
|
677
|
-
request = service_pb2.GetWorkflowRequest(user_app_id=self.user_app_id, workflow_id=workflow_id)
|
678
|
-
response = self._grpc_request(self.STUB.GetWorkflow, request)
|
679
|
-
|
680
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
681
|
-
raise Exception(response.status)
|
682
|
-
dict_response = MessageToDict(response, preserving_proto_field_name=True)
|
683
|
-
kwargs = self.process_response_keys(dict_response[list(dict_response.keys())[1]],
|
684
|
-
list(dict_response.keys())[1])
|
685
|
-
|
686
|
-
return Workflow.from_auth_helper(auth=self.auth_helper, **kwargs)
|
687
|
-
|
688
|
-
def module(self, module_id: str, **kwargs) -> Module:
|
689
|
-
"""Returns a Module object for the existing module ID.
|
690
|
-
|
691
|
-
Args:
|
692
|
-
module_id (str): The module ID for the module to interact with.
|
693
|
-
module_version_id (str): The module version ID for the module version to interact with.
|
694
|
-
|
695
|
-
Returns:
|
696
|
-
Module: A Module object for the existing module ID.
|
697
|
-
|
698
|
-
Example:
|
699
|
-
>>> from clarifai.client.app import App
|
700
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
701
|
-
>>> module = app.module(module_id="module_id")
|
702
|
-
"""
|
703
|
-
request = service_pb2.GetModuleRequest(user_app_id=self.user_app_id, module_id=module_id)
|
704
|
-
response = self._grpc_request(self.STUB.GetModule, request)
|
705
|
-
|
706
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
707
|
-
raise Exception(response.status)
|
708
|
-
dict_response = MessageToDict(response, preserving_proto_field_name=True)
|
709
|
-
kwargs = self.process_response_keys(dict_response['module'], 'module')
|
710
|
-
|
711
|
-
return Module.from_auth_helper(auth=self.auth_helper, **kwargs)
|
712
|
-
|
713
|
-
def inputs(self,):
|
714
|
-
"""Returns an Input object.
|
715
|
-
|
716
|
-
Returns:
|
717
|
-
Inputs: An input object.
|
718
|
-
"""
|
719
|
-
return Inputs.from_auth_helper(self.auth_helper)
|
720
|
-
|
721
|
-
def patch_dataset(self, dataset_id: str, action: str = 'merge', **kwargs) -> Dataset:
|
722
|
-
"""Patches a dataset for the app.
|
723
|
-
|
724
|
-
Args:
|
725
|
-
dataset_id (str): The dataset ID for the dataset to create.
|
726
|
-
action (str): The action to perform on the dataset (merge/overwrite/remove).
|
727
|
-
**kwargs: Additional keyword arguments to be passed to patch the Dataset.
|
728
|
-
|
729
|
-
Returns:
|
730
|
-
Dataset: A Dataset object for the specified dataset ID.
|
731
|
-
"""
|
732
|
-
if "visibility" in kwargs:
|
733
|
-
kwargs["visibility"] = resources_pb2.Visibility(gettable=kwargs["visibility"])
|
734
|
-
if "image_url" in kwargs:
|
735
|
-
kwargs["image"] = resources_pb2.Image(url=kwargs.pop("image_url"))
|
736
|
-
request = service_pb2.PatchDatasetsRequest(
|
737
|
-
user_app_id=self.user_app_id,
|
738
|
-
datasets=[resources_pb2.Dataset(id=dataset_id, **kwargs)],
|
739
|
-
action=action)
|
740
|
-
response = self._grpc_request(self.STUB.PatchDatasets, request)
|
741
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
742
|
-
raise Exception(response.status)
|
743
|
-
self.logger.info("\nDataset patched\n%s", response.status)
|
744
|
-
|
745
|
-
return Dataset.from_auth_helper(self.auth_helper, dataset_id=dataset_id, **kwargs)
|
746
|
-
|
747
|
-
def patch_model(self, model_id: str, action: str = 'merge', **kwargs) -> Model:
|
748
|
-
"""Patches a model of the app.
|
749
|
-
|
750
|
-
Args:
|
751
|
-
model_id (str): The model ID of the model to patch.
|
752
|
-
action (str): The action to perform on the model (merge/overwrite/remove).
|
753
|
-
**kwargs: Additional keyword arguments to be passed to patch the Model.
|
754
|
-
|
755
|
-
Returns:
|
756
|
-
Model: A Model object of the specified model ID.
|
757
|
-
"""
|
758
|
-
if "visibility" in kwargs:
|
759
|
-
kwargs["visibility"] = resources_pb2.Visibility(gettable=kwargs["visibility"])
|
760
|
-
if "image_url" in kwargs:
|
761
|
-
kwargs["image"] = resources_pb2.Image(url=kwargs.pop("image_url"))
|
762
|
-
request = service_pb2.PatchModelsRequest(
|
763
|
-
user_app_id=self.user_app_id,
|
764
|
-
models=[resources_pb2.Model(id=model_id, **kwargs)],
|
765
|
-
action=action)
|
766
|
-
response = self._grpc_request(self.STUB.PatchModels, request)
|
767
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
768
|
-
raise Exception(response.status)
|
769
|
-
self.logger.info("\nModel %s patched successfully\n%s", model_id, response.status)
|
770
|
-
kwargs.update({
|
771
|
-
'model_id': model_id,
|
772
|
-
})
|
773
|
-
|
774
|
-
return Model.from_auth_helper(self.auth_helper, **kwargs)
|
775
|
-
|
776
|
-
def patch_workflow(self,
|
777
|
-
workflow_id: str,
|
778
|
-
action: str = 'merge',
|
779
|
-
config_filepath: str = None,
|
780
|
-
**kwargs) -> Workflow:
|
781
|
-
"""Patches a workflow of the app.
|
782
|
-
|
783
|
-
Args:
|
784
|
-
workflow_id (str): The Workflow ID of the workflow to patch.
|
785
|
-
action (str): The action to perform on the workflow (merge/overwrite/remove).
|
786
|
-
config_filepath (str): The path to the yaml workflow config file.
|
787
|
-
**kwargs: Additional keyword arguments to be passed to patch the Workflow.
|
788
|
-
|
789
|
-
Returns:
|
790
|
-
Workflow: A Workflow object of the specified workflow ID.
|
791
|
-
"""
|
792
|
-
if config_filepath:
|
793
|
-
if not os.path.exists(config_filepath):
|
794
|
-
raise UserError(f"Workflow config file not found at {config_filepath}")
|
795
|
-
_, kwargs['nodes'] = self._process_workflow_config(config_filepath)
|
796
|
-
if "visibility" in kwargs:
|
797
|
-
kwargs["visibility"] = resources_pb2.Visibility(gettable=kwargs["visibility"])
|
798
|
-
if "image_url" in kwargs:
|
799
|
-
kwargs["image"] = resources_pb2.Image(url=kwargs.pop("image_url"))
|
800
|
-
|
801
|
-
request = service_pb2.PatchWorkflowsRequest(
|
802
|
-
user_app_id=self.user_app_id,
|
803
|
-
workflows=[resources_pb2.Workflow(id=workflow_id, **kwargs)],
|
804
|
-
action=action)
|
805
|
-
response = self._grpc_request(self.STUB.PatchWorkflows, request)
|
806
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
807
|
-
raise Exception(response.status)
|
808
|
-
self.logger.info("\nWorkflow patched\n%s", response.status)
|
809
|
-
kwargs.update({
|
810
|
-
'workflow_id': workflow_id,
|
811
|
-
})
|
812
|
-
|
813
|
-
return Workflow.from_auth_helper(self.auth_helper, **kwargs)
|
814
|
-
|
815
|
-
def delete_dataset(self, dataset_id: str) -> None:
|
816
|
-
"""Deletes an dataset for the user.
|
817
|
-
|
818
|
-
Args:
|
819
|
-
dataset_id (str): The dataset ID for the app to delete.
|
820
|
-
|
821
|
-
Example:
|
822
|
-
>>> from clarifai.client.app import App
|
823
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
824
|
-
>>> app.delete_dataset(dataset_id="dataset_id")
|
825
|
-
"""
|
826
|
-
request = service_pb2.DeleteDatasetsRequest(
|
827
|
-
user_app_id=self.user_app_id, dataset_ids=[dataset_id])
|
828
|
-
response = self._grpc_request(self.STUB.DeleteDatasets, request)
|
829
|
-
|
830
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
831
|
-
raise Exception(response.status)
|
832
|
-
self.logger.info("\nDataset Deleted\n%s", response.status)
|
833
|
-
|
834
|
-
def delete_model(self, model_id: str) -> None:
|
835
|
-
"""Deletes an model for the user.
|
836
|
-
|
837
|
-
Args:
|
838
|
-
model_id (str): The model ID for the app to delete.
|
839
|
-
|
840
|
-
Example:
|
841
|
-
>>> from clarifai.client.app import App
|
842
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
843
|
-
>>> app.delete_model(model_id="model_id")
|
844
|
-
"""
|
845
|
-
request = service_pb2.DeleteModelsRequest(user_app_id=self.user_app_id, ids=[model_id])
|
846
|
-
response = self._grpc_request(self.STUB.DeleteModels, request)
|
847
|
-
|
848
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
849
|
-
raise Exception(response.status)
|
850
|
-
self.logger.info("\nModel Deleted\n%s", response.status)
|
851
|
-
|
852
|
-
def delete_workflow(self, workflow_id: str) -> None:
|
853
|
-
"""Deletes an workflow for the user.
|
854
|
-
|
855
|
-
Args:
|
856
|
-
workflow_id (str): The workflow ID for the app to delete.
|
857
|
-
|
858
|
-
Example:
|
859
|
-
>>> from clarifai.client.app import App
|
860
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
861
|
-
>>> app.delete_workflow(workflow_id="workflow_id")
|
862
|
-
"""
|
863
|
-
request = service_pb2.DeleteWorkflowsRequest(user_app_id=self.user_app_id, ids=[workflow_id])
|
864
|
-
response = self._grpc_request(self.STUB.DeleteWorkflows, request)
|
865
|
-
|
866
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
867
|
-
raise Exception(response.status)
|
868
|
-
self.logger.info("\nWorkflow Deleted\n%s", response.status)
|
869
|
-
|
870
|
-
def delete_module(self, module_id: str) -> None:
|
871
|
-
"""Deletes an module for the user.
|
872
|
-
|
873
|
-
Args:
|
874
|
-
module_id (str): The module ID for the app to delete.
|
875
|
-
|
876
|
-
Example:
|
877
|
-
>>> from clarifai.client.app import App
|
878
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
879
|
-
>>> app.delete_module(module_id="module_id")
|
880
|
-
"""
|
881
|
-
request = service_pb2.DeleteModulesRequest(user_app_id=self.user_app_id, ids=[module_id])
|
882
|
-
response = self._grpc_request(self.STUB.DeleteModules, request)
|
883
|
-
|
884
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
885
|
-
raise Exception(response.status)
|
886
|
-
self.logger.info("\nModule Deleted\n%s", response.status)
|
887
|
-
|
888
|
-
def delete_concept_relations(self, concept_id: str,
|
889
|
-
concept_relation_ids: List[str] = []) -> None:
|
890
|
-
"""Delete concept relations of a concept of the app.
|
891
|
-
|
892
|
-
Args:
|
893
|
-
concept_id (str): The concept ID of the concept to delete relations for.
|
894
|
-
concept_relation_ids (List[str], optional): List of concept relation IDs of concept relations.
|
895
|
-
|
896
|
-
Example:
|
897
|
-
>>> from clarifai.client.app import App
|
898
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
899
|
-
>>> app.delete_concept_relations(concept_id="concept_id", concept_relation_ids=["concept_relation_id_1", "concept_relation_id_2", ..])
|
900
|
-
"""
|
901
|
-
if not concept_relation_ids:
|
902
|
-
concept_relation_ids = [
|
903
|
-
concept_relation.id
|
904
|
-
for concept_relation in list(self.search_concept_relations(concept_id=concept_id))
|
905
|
-
]
|
906
|
-
request = service_pb2.DeleteConceptRelationsRequest(
|
907
|
-
user_app_id=self.user_app_id, concept_id=concept_id, ids=concept_relation_ids)
|
908
|
-
response = self._grpc_request(self.STUB.DeleteConceptRelations, request)
|
909
|
-
if response.status.code != status_code_pb2.SUCCESS:
|
910
|
-
raise Exception(response.status)
|
911
|
-
self.logger.info("\nConcept Relations Deleted\n%s", response.status)
|
912
|
-
|
913
|
-
def search(self, **kwargs) -> Model:
|
914
|
-
"""Returns a Search object for the user and app ID.
|
915
|
-
|
916
|
-
Args:
|
917
|
-
see the Search class in clarifai.client.search for kwargs.
|
918
|
-
|
919
|
-
Returns:
|
920
|
-
Search: A Search object for the user and app ID.
|
921
|
-
|
922
|
-
Example:
|
923
|
-
>>> from clarifai.client.app import App
|
924
|
-
>>> app = App(app_id="app_id", user_id="user_id")
|
925
|
-
>>> search_client = app.search(top_k=12, metric="euclidean")
|
926
|
-
"""
|
927
|
-
kwargs.get("user_id", self.user_app_id.user_id)
|
928
|
-
kwargs.get("app_id", self.user_app_id.app_id)
|
929
|
-
return Search.from_auth_helper(auth=self.auth_helper, **kwargs)
|
930
|
-
|
931
|
-
def __getattr__(self, name):
|
932
|
-
return getattr(self.app_info, name)
|
933
|
-
|
934
|
-
def __str__(self):
|
935
|
-
init_params = [param for param in self.kwargs.keys()]
|
936
|
-
attribute_strings = [
|
937
|
-
f"{param}={getattr(self.app_info, param)}" for param in init_params
|
938
|
-
if hasattr(self.app_info, param)
|
939
|
-
]
|
940
|
-
return f"Clarifai App Details: \n{', '.join(attribute_strings)}\n"
|
764
|
+
):
|
765
|
+
"""Returns an Input object.
|
766
|
+
|
767
|
+
Returns:
|
768
|
+
Inputs: An input object.
|
769
|
+
"""
|
770
|
+
return Inputs.from_auth_helper(self.auth_helper)
|
771
|
+
|
772
|
+
def patch_dataset(self, dataset_id: str, action: str = 'merge', **kwargs) -> Dataset:
|
773
|
+
"""Patches a dataset for the app.
|
774
|
+
|
775
|
+
Args:
|
776
|
+
dataset_id (str): The dataset ID for the dataset to create.
|
777
|
+
action (str): The action to perform on the dataset (merge/overwrite/remove).
|
778
|
+
**kwargs: Additional keyword arguments to be passed to patch the Dataset.
|
779
|
+
|
780
|
+
Returns:
|
781
|
+
Dataset: A Dataset object for the specified dataset ID.
|
782
|
+
"""
|
783
|
+
if "visibility" in kwargs:
|
784
|
+
kwargs["visibility"] = resources_pb2.Visibility(gettable=kwargs["visibility"])
|
785
|
+
if "image_url" in kwargs:
|
786
|
+
kwargs["image"] = resources_pb2.Image(url=kwargs.pop("image_url"))
|
787
|
+
request = service_pb2.PatchDatasetsRequest(
|
788
|
+
user_app_id=self.user_app_id,
|
789
|
+
datasets=[resources_pb2.Dataset(id=dataset_id, **kwargs)],
|
790
|
+
action=action,
|
791
|
+
)
|
792
|
+
response = self._grpc_request(self.STUB.PatchDatasets, request)
|
793
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
794
|
+
raise Exception(response.status)
|
795
|
+
self.logger.info("\nDataset patched\n%s", response.status)
|
796
|
+
|
797
|
+
return Dataset.from_auth_helper(self.auth_helper, dataset_id=dataset_id, **kwargs)
|
798
|
+
|
799
|
+
def patch_model(self, model_id: str, action: str = 'merge', **kwargs) -> Model:
|
800
|
+
"""Patches a model of the app.
|
801
|
+
|
802
|
+
Args:
|
803
|
+
model_id (str): The model ID of the model to patch.
|
804
|
+
action (str): The action to perform on the model (merge/overwrite/remove).
|
805
|
+
**kwargs: Additional keyword arguments to be passed to patch the Model.
|
806
|
+
|
807
|
+
Returns:
|
808
|
+
Model: A Model object of the specified model ID.
|
809
|
+
"""
|
810
|
+
if "visibility" in kwargs:
|
811
|
+
kwargs["visibility"] = resources_pb2.Visibility(gettable=kwargs["visibility"])
|
812
|
+
if "image_url" in kwargs:
|
813
|
+
kwargs["image"] = resources_pb2.Image(url=kwargs.pop("image_url"))
|
814
|
+
request = service_pb2.PatchModelsRequest(
|
815
|
+
user_app_id=self.user_app_id,
|
816
|
+
models=[resources_pb2.Model(id=model_id, **kwargs)],
|
817
|
+
action=action,
|
818
|
+
)
|
819
|
+
response = self._grpc_request(self.STUB.PatchModels, request)
|
820
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
821
|
+
raise Exception(response.status)
|
822
|
+
self.logger.info("\nModel %s patched successfully\n%s", model_id, response.status)
|
823
|
+
kwargs.update(
|
824
|
+
{
|
825
|
+
'model_id': model_id,
|
826
|
+
}
|
827
|
+
)
|
828
|
+
|
829
|
+
return Model.from_auth_helper(self.auth_helper, **kwargs)
|
830
|
+
|
831
|
+
def patch_workflow(
|
832
|
+
self, workflow_id: str, action: str = 'merge', config_filepath: str = None, **kwargs
|
833
|
+
) -> Workflow:
|
834
|
+
"""Patches a workflow of the app.
|
835
|
+
|
836
|
+
Args:
|
837
|
+
workflow_id (str): The Workflow ID of the workflow to patch.
|
838
|
+
action (str): The action to perform on the workflow (merge/overwrite/remove).
|
839
|
+
config_filepath (str): The path to the yaml workflow config file.
|
840
|
+
**kwargs: Additional keyword arguments to be passed to patch the Workflow.
|
841
|
+
|
842
|
+
Returns:
|
843
|
+
Workflow: A Workflow object of the specified workflow ID.
|
844
|
+
"""
|
845
|
+
if config_filepath:
|
846
|
+
if not os.path.exists(config_filepath):
|
847
|
+
raise UserError(f"Workflow config file not found at {config_filepath}")
|
848
|
+
_, kwargs['nodes'] = self._process_workflow_config(config_filepath)
|
849
|
+
if "visibility" in kwargs:
|
850
|
+
kwargs["visibility"] = resources_pb2.Visibility(gettable=kwargs["visibility"])
|
851
|
+
if "image_url" in kwargs:
|
852
|
+
kwargs["image"] = resources_pb2.Image(url=kwargs.pop("image_url"))
|
853
|
+
|
854
|
+
request = service_pb2.PatchWorkflowsRequest(
|
855
|
+
user_app_id=self.user_app_id,
|
856
|
+
workflows=[resources_pb2.Workflow(id=workflow_id, **kwargs)],
|
857
|
+
action=action,
|
858
|
+
)
|
859
|
+
response = self._grpc_request(self.STUB.PatchWorkflows, request)
|
860
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
861
|
+
raise Exception(response.status)
|
862
|
+
self.logger.info("\nWorkflow patched\n%s", response.status)
|
863
|
+
kwargs.update(
|
864
|
+
{
|
865
|
+
'workflow_id': workflow_id,
|
866
|
+
}
|
867
|
+
)
|
868
|
+
|
869
|
+
return Workflow.from_auth_helper(self.auth_helper, **kwargs)
|
870
|
+
|
871
|
+
def delete_dataset(self, dataset_id: str) -> None:
|
872
|
+
"""Deletes an dataset for the user.
|
873
|
+
|
874
|
+
Args:
|
875
|
+
dataset_id (str): The dataset ID for the app to delete.
|
876
|
+
|
877
|
+
Example:
|
878
|
+
>>> from clarifai.client.app import App
|
879
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
880
|
+
>>> app.delete_dataset(dataset_id="dataset_id")
|
881
|
+
"""
|
882
|
+
request = service_pb2.DeleteDatasetsRequest(
|
883
|
+
user_app_id=self.user_app_id, dataset_ids=[dataset_id]
|
884
|
+
)
|
885
|
+
response = self._grpc_request(self.STUB.DeleteDatasets, request)
|
886
|
+
|
887
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
888
|
+
raise Exception(response.status)
|
889
|
+
self.logger.info("\nDataset Deleted\n%s", response.status)
|
890
|
+
|
891
|
+
def delete_model(self, model_id: str) -> None:
|
892
|
+
"""Deletes an model for the user.
|
893
|
+
|
894
|
+
Args:
|
895
|
+
model_id (str): The model ID for the app to delete.
|
896
|
+
|
897
|
+
Example:
|
898
|
+
>>> from clarifai.client.app import App
|
899
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
900
|
+
>>> app.delete_model(model_id="model_id")
|
901
|
+
"""
|
902
|
+
request = service_pb2.DeleteModelsRequest(user_app_id=self.user_app_id, ids=[model_id])
|
903
|
+
response = self._grpc_request(self.STUB.DeleteModels, request)
|
904
|
+
|
905
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
906
|
+
raise Exception(response.status)
|
907
|
+
self.logger.info("\nModel Deleted\n%s", response.status)
|
908
|
+
|
909
|
+
def delete_workflow(self, workflow_id: str) -> None:
|
910
|
+
"""Deletes an workflow for the user.
|
911
|
+
|
912
|
+
Args:
|
913
|
+
workflow_id (str): The workflow ID for the app to delete.
|
914
|
+
|
915
|
+
Example:
|
916
|
+
>>> from clarifai.client.app import App
|
917
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
918
|
+
>>> app.delete_workflow(workflow_id="workflow_id")
|
919
|
+
"""
|
920
|
+
request = service_pb2.DeleteWorkflowsRequest(
|
921
|
+
user_app_id=self.user_app_id, ids=[workflow_id]
|
922
|
+
)
|
923
|
+
response = self._grpc_request(self.STUB.DeleteWorkflows, request)
|
924
|
+
|
925
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
926
|
+
raise Exception(response.status)
|
927
|
+
self.logger.info("\nWorkflow Deleted\n%s", response.status)
|
928
|
+
|
929
|
+
def delete_module(self, module_id: str) -> None:
|
930
|
+
"""Deletes an module for the user.
|
931
|
+
|
932
|
+
Args:
|
933
|
+
module_id (str): The module ID for the app to delete.
|
934
|
+
|
935
|
+
Example:
|
936
|
+
>>> from clarifai.client.app import App
|
937
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
938
|
+
>>> app.delete_module(module_id="module_id")
|
939
|
+
"""
|
940
|
+
request = service_pb2.DeleteModulesRequest(user_app_id=self.user_app_id, ids=[module_id])
|
941
|
+
response = self._grpc_request(self.STUB.DeleteModules, request)
|
942
|
+
|
943
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
944
|
+
raise Exception(response.status)
|
945
|
+
self.logger.info("\nModule Deleted\n%s", response.status)
|
946
|
+
|
947
|
+
def delete_concept_relations(
|
948
|
+
self, concept_id: str, concept_relation_ids: List[str] = []
|
949
|
+
) -> None:
|
950
|
+
"""Delete concept relations of a concept of the app.
|
951
|
+
|
952
|
+
Args:
|
953
|
+
concept_id (str): The concept ID of the concept to delete relations for.
|
954
|
+
concept_relation_ids (List[str], optional): List of concept relation IDs of concept relations.
|
955
|
+
|
956
|
+
Example:
|
957
|
+
>>> from clarifai.client.app import App
|
958
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
959
|
+
>>> app.delete_concept_relations(concept_id="concept_id", concept_relation_ids=["concept_relation_id_1", "concept_relation_id_2", ..])
|
960
|
+
"""
|
961
|
+
if not concept_relation_ids:
|
962
|
+
concept_relation_ids = [
|
963
|
+
concept_relation.id
|
964
|
+
for concept_relation in list(self.search_concept_relations(concept_id=concept_id))
|
965
|
+
]
|
966
|
+
request = service_pb2.DeleteConceptRelationsRequest(
|
967
|
+
user_app_id=self.user_app_id, concept_id=concept_id, ids=concept_relation_ids
|
968
|
+
)
|
969
|
+
response = self._grpc_request(self.STUB.DeleteConceptRelations, request)
|
970
|
+
if response.status.code != status_code_pb2.SUCCESS:
|
971
|
+
raise Exception(response.status)
|
972
|
+
self.logger.info("\nConcept Relations Deleted\n%s", response.status)
|
973
|
+
|
974
|
+
def search(self, **kwargs) -> Model:
|
975
|
+
"""Returns a Search object for the user and app ID.
|
976
|
+
|
977
|
+
Args:
|
978
|
+
see the Search class in clarifai.client.search for kwargs.
|
979
|
+
|
980
|
+
Returns:
|
981
|
+
Search: A Search object for the user and app ID.
|
982
|
+
|
983
|
+
Example:
|
984
|
+
>>> from clarifai.client.app import App
|
985
|
+
>>> app = App(app_id="app_id", user_id="user_id")
|
986
|
+
>>> search_client = app.search(top_k=12, metric="euclidean")
|
987
|
+
"""
|
988
|
+
kwargs.get("user_id", self.user_app_id.user_id)
|
989
|
+
kwargs.get("app_id", self.user_app_id.app_id)
|
990
|
+
return Search.from_auth_helper(auth=self.auth_helper, **kwargs)
|
991
|
+
|
992
|
+
def __getattr__(self, name):
|
993
|
+
return getattr(self.app_info, name)
|
994
|
+
|
995
|
+
def __str__(self):
|
996
|
+
init_params = [param for param in self.kwargs.keys()]
|
997
|
+
attribute_strings = [
|
998
|
+
f"{param}={getattr(self.app_info, param)}"
|
999
|
+
for param in init_params
|
1000
|
+
if hasattr(self.app_info, param)
|
1001
|
+
]
|
1002
|
+
return f"Clarifai App Details: \n{', '.join(attribute_strings)}\n"
|