clarifai 11.7.4__py3-none-any.whl → 11.7.5rc1__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.
Files changed (231) hide show
  1. clarifai/__init__.py +1 -1
  2. clarifai/__pycache__/__init__.cpython-311.pyc +0 -0
  3. clarifai/__pycache__/__init__.cpython-312.pyc +0 -0
  4. clarifai/__pycache__/__init__.cpython-39.pyc +0 -0
  5. clarifai/__pycache__/errors.cpython-311.pyc +0 -0
  6. clarifai/__pycache__/errors.cpython-39.pyc +0 -0
  7. clarifai/__pycache__/versions.cpython-311.pyc +0 -0
  8. clarifai/__pycache__/versions.cpython-39.pyc +0 -0
  9. clarifai/cli/__pycache__/__init__.cpython-311.pyc +0 -0
  10. clarifai/cli/__pycache__/__init__.cpython-39.pyc +0 -0
  11. clarifai/cli/__pycache__/base.cpython-311.pyc +0 -0
  12. clarifai/cli/__pycache__/base.cpython-39.pyc +0 -0
  13. clarifai/cli/__pycache__/compute_cluster.cpython-311.pyc +0 -0
  14. clarifai/cli/__pycache__/compute_cluster.cpython-39.pyc +0 -0
  15. clarifai/cli/__pycache__/deployment.cpython-311.pyc +0 -0
  16. clarifai/cli/__pycache__/deployment.cpython-39.pyc +0 -0
  17. clarifai/cli/__pycache__/model.cpython-311.pyc +0 -0
  18. clarifai/cli/__pycache__/model.cpython-39.pyc +0 -0
  19. clarifai/cli/__pycache__/nodepool.cpython-311.pyc +0 -0
  20. clarifai/cli/__pycache__/nodepool.cpython-39.pyc +0 -0
  21. clarifai/cli/__pycache__/pipeline.cpython-311.pyc +0 -0
  22. clarifai/cli/__pycache__/pipeline_step.cpython-311.pyc +0 -0
  23. clarifai/cli/base.py +2 -2
  24. clarifai/cli/model.py +264 -144
  25. clarifai/cli/model_templates.py +243 -0
  26. clarifai/cli/pipeline.py +31 -11
  27. clarifai/cli/pipeline_step_templates.py +64 -0
  28. clarifai/cli/templates/__pycache__/__init__.cpython-311.pyc +0 -0
  29. clarifai/cli/templates/__pycache__/pipeline_templates.cpython-311.pyc +0 -0
  30. clarifai/cli/templates/pipeline_templates.py +34 -28
  31. clarifai/client/__pycache__/__init__.cpython-311.pyc +0 -0
  32. clarifai/client/__pycache__/__init__.cpython-312.pyc +0 -0
  33. clarifai/client/__pycache__/__init__.cpython-39.pyc +0 -0
  34. clarifai/client/__pycache__/app.cpython-311.pyc +0 -0
  35. clarifai/client/__pycache__/app.cpython-312.pyc +0 -0
  36. clarifai/client/__pycache__/app.cpython-39.pyc +0 -0
  37. clarifai/client/__pycache__/base.cpython-311.pyc +0 -0
  38. clarifai/client/__pycache__/base.cpython-39.pyc +0 -0
  39. clarifai/client/__pycache__/compute_cluster.cpython-311.pyc +0 -0
  40. clarifai/client/__pycache__/dataset.cpython-311.pyc +0 -0
  41. clarifai/client/__pycache__/dataset.cpython-39.pyc +0 -0
  42. clarifai/client/__pycache__/deployment.cpython-311.pyc +0 -0
  43. clarifai/client/__pycache__/deployment.cpython-39.pyc +0 -0
  44. clarifai/client/__pycache__/input.cpython-311.pyc +0 -0
  45. clarifai/client/__pycache__/input.cpython-39.pyc +0 -0
  46. clarifai/client/__pycache__/lister.cpython-311.pyc +0 -0
  47. clarifai/client/__pycache__/lister.cpython-39.pyc +0 -0
  48. clarifai/client/__pycache__/model.cpython-311.pyc +0 -0
  49. clarifai/client/__pycache__/model.cpython-39.pyc +0 -0
  50. clarifai/client/__pycache__/model_client.cpython-311.pyc +0 -0
  51. clarifai/client/__pycache__/model_client.cpython-39.pyc +0 -0
  52. clarifai/client/__pycache__/module.cpython-311.pyc +0 -0
  53. clarifai/client/__pycache__/nodepool.cpython-311.pyc +0 -0
  54. clarifai/client/__pycache__/pipeline.cpython-311.pyc +0 -0
  55. clarifai/client/__pycache__/pipeline_step.cpython-311.pyc +0 -0
  56. clarifai/client/__pycache__/runner.cpython-311.pyc +0 -0
  57. clarifai/client/__pycache__/search.cpython-311.pyc +0 -0
  58. clarifai/client/__pycache__/user.cpython-311.pyc +0 -0
  59. clarifai/client/__pycache__/workflow.cpython-311.pyc +0 -0
  60. clarifai/client/auth/__pycache__/__init__.cpython-311.pyc +0 -0
  61. clarifai/client/auth/__pycache__/__init__.cpython-39.pyc +0 -0
  62. clarifai/client/auth/__pycache__/helper.cpython-311.pyc +0 -0
  63. clarifai/client/auth/__pycache__/helper.cpython-39.pyc +0 -0
  64. clarifai/client/auth/__pycache__/register.cpython-311.pyc +0 -0
  65. clarifai/client/auth/__pycache__/register.cpython-39.pyc +0 -0
  66. clarifai/client/auth/__pycache__/stub.cpython-311.pyc +0 -0
  67. clarifai/client/auth/__pycache__/stub.cpython-39.pyc +0 -0
  68. clarifai/client/pipeline.py +20 -4
  69. clarifai/client/user.py +172 -0
  70. clarifai/constants/__pycache__/base.cpython-311.pyc +0 -0
  71. clarifai/constants/__pycache__/base.cpython-39.pyc +0 -0
  72. clarifai/constants/__pycache__/dataset.cpython-311.pyc +0 -0
  73. clarifai/constants/__pycache__/dataset.cpython-39.pyc +0 -0
  74. clarifai/constants/__pycache__/input.cpython-311.pyc +0 -0
  75. clarifai/constants/__pycache__/input.cpython-39.pyc +0 -0
  76. clarifai/constants/__pycache__/model.cpython-311.pyc +0 -0
  77. clarifai/constants/__pycache__/model.cpython-39.pyc +0 -0
  78. clarifai/constants/__pycache__/rag.cpython-311.pyc +0 -0
  79. clarifai/constants/__pycache__/search.cpython-311.pyc +0 -0
  80. clarifai/constants/__pycache__/workflow.cpython-311.pyc +0 -0
  81. clarifai/datasets/__pycache__/__init__.cpython-311.pyc +0 -0
  82. clarifai/datasets/__pycache__/__init__.cpython-39.pyc +0 -0
  83. clarifai/datasets/export/__pycache__/__init__.cpython-311.pyc +0 -0
  84. clarifai/datasets/export/__pycache__/__init__.cpython-39.pyc +0 -0
  85. clarifai/datasets/export/__pycache__/inputs_annotations.cpython-311.pyc +0 -0
  86. clarifai/datasets/export/__pycache__/inputs_annotations.cpython-39.pyc +0 -0
  87. clarifai/datasets/upload/__pycache__/__init__.cpython-311.pyc +0 -0
  88. clarifai/datasets/upload/__pycache__/__init__.cpython-39.pyc +0 -0
  89. clarifai/datasets/upload/__pycache__/base.cpython-311.pyc +0 -0
  90. clarifai/datasets/upload/__pycache__/base.cpython-39.pyc +0 -0
  91. clarifai/datasets/upload/__pycache__/features.cpython-311.pyc +0 -0
  92. clarifai/datasets/upload/__pycache__/features.cpython-39.pyc +0 -0
  93. clarifai/datasets/upload/__pycache__/image.cpython-311.pyc +0 -0
  94. clarifai/datasets/upload/__pycache__/image.cpython-39.pyc +0 -0
  95. clarifai/datasets/upload/__pycache__/multimodal.cpython-311.pyc +0 -0
  96. clarifai/datasets/upload/__pycache__/multimodal.cpython-39.pyc +0 -0
  97. clarifai/datasets/upload/__pycache__/text.cpython-311.pyc +0 -0
  98. clarifai/datasets/upload/__pycache__/text.cpython-39.pyc +0 -0
  99. clarifai/datasets/upload/__pycache__/utils.cpython-311.pyc +0 -0
  100. clarifai/datasets/upload/__pycache__/utils.cpython-39.pyc +0 -0
  101. clarifai/datasets/upload/loaders/__pycache__/__init__.cpython-311.pyc +0 -0
  102. clarifai/datasets/upload/loaders/__pycache__/coco_detection.cpython-311.pyc +0 -0
  103. clarifai/datasets/upload/loaders/__pycache__/imagenet_classification.cpython-311.pyc +0 -0
  104. clarifai/models/model_serving/README.md +158 -0
  105. clarifai/models/model_serving/__init__.py +14 -0
  106. clarifai/models/model_serving/cli/__init__.py +12 -0
  107. clarifai/models/model_serving/cli/_utils.py +53 -0
  108. clarifai/models/model_serving/cli/base.py +14 -0
  109. clarifai/models/model_serving/cli/build.py +79 -0
  110. clarifai/models/model_serving/cli/clarifai_clis.py +33 -0
  111. clarifai/models/model_serving/cli/create.py +171 -0
  112. clarifai/models/model_serving/cli/example_cli.py +34 -0
  113. clarifai/models/model_serving/cli/login.py +26 -0
  114. clarifai/models/model_serving/cli/upload.py +179 -0
  115. clarifai/models/model_serving/constants.py +21 -0
  116. clarifai/models/model_serving/docs/cli.md +161 -0
  117. clarifai/models/model_serving/docs/concepts.md +229 -0
  118. clarifai/models/model_serving/docs/dependencies.md +11 -0
  119. clarifai/models/model_serving/docs/inference_parameters.md +139 -0
  120. clarifai/models/model_serving/docs/model_types.md +19 -0
  121. clarifai/models/model_serving/model_config/__init__.py +16 -0
  122. clarifai/models/model_serving/model_config/base.py +369 -0
  123. clarifai/models/model_serving/model_config/config.py +312 -0
  124. clarifai/models/model_serving/model_config/inference_parameter.py +129 -0
  125. clarifai/models/model_serving/model_config/model_types_config/multimodal-embedder.yaml +25 -0
  126. clarifai/models/model_serving/model_config/model_types_config/text-classifier.yaml +19 -0
  127. clarifai/models/model_serving/model_config/model_types_config/text-embedder.yaml +20 -0
  128. clarifai/models/model_serving/model_config/model_types_config/text-to-image.yaml +19 -0
  129. clarifai/models/model_serving/model_config/model_types_config/text-to-text.yaml +19 -0
  130. clarifai/models/model_serving/model_config/model_types_config/visual-classifier.yaml +22 -0
  131. clarifai/models/model_serving/model_config/model_types_config/visual-detector.yaml +32 -0
  132. clarifai/models/model_serving/model_config/model_types_config/visual-embedder.yaml +19 -0
  133. clarifai/models/model_serving/model_config/model_types_config/visual-segmenter.yaml +19 -0
  134. clarifai/models/model_serving/model_config/output.py +133 -0
  135. clarifai/models/model_serving/model_config/triton/__init__.py +14 -0
  136. clarifai/models/model_serving/model_config/triton/serializer.py +136 -0
  137. clarifai/models/model_serving/model_config/triton/triton_config.py +182 -0
  138. clarifai/models/model_serving/model_config/triton/wrappers.py +281 -0
  139. clarifai/models/model_serving/repo_build/__init__.py +14 -0
  140. clarifai/models/model_serving/repo_build/build.py +198 -0
  141. clarifai/models/model_serving/repo_build/static_files/_requirements.txt +2 -0
  142. clarifai/models/model_serving/repo_build/static_files/base_test.py +169 -0
  143. clarifai/models/model_serving/repo_build/static_files/inference.py +26 -0
  144. clarifai/models/model_serving/repo_build/static_files/sample_clarifai_config.yaml +25 -0
  145. clarifai/models/model_serving/repo_build/static_files/test.py +40 -0
  146. clarifai/models/model_serving/repo_build/static_files/triton/model.py +75 -0
  147. clarifai/models/model_serving/utils.py +23 -0
  148. clarifai/rag/__pycache__/__init__.cpython-311.pyc +0 -0
  149. clarifai/rag/__pycache__/rag.cpython-311.pyc +0 -0
  150. clarifai/rag/__pycache__/utils.cpython-311.pyc +0 -0
  151. clarifai/runners/__pycache__/__init__.cpython-311.pyc +0 -0
  152. clarifai/runners/__pycache__/__init__.cpython-39.pyc +0 -0
  153. clarifai/runners/models/__pycache__/__init__.cpython-311.pyc +0 -0
  154. clarifai/runners/models/__pycache__/__init__.cpython-39.pyc +0 -0
  155. clarifai/runners/models/__pycache__/dummy_openai_model.cpython-311.pyc +0 -0
  156. clarifai/runners/models/__pycache__/mcp_class.cpython-311.pyc +0 -0
  157. clarifai/runners/models/__pycache__/model_builder.cpython-311.pyc +0 -0
  158. clarifai/runners/models/__pycache__/model_builder.cpython-39.pyc +0 -0
  159. clarifai/runners/models/__pycache__/model_class.cpython-311.pyc +0 -0
  160. clarifai/runners/models/__pycache__/model_run_locally.cpython-311.pyc +0 -0
  161. clarifai/runners/models/__pycache__/model_runner.cpython-311.pyc +0 -0
  162. clarifai/runners/models/__pycache__/model_servicer.cpython-311.pyc +0 -0
  163. clarifai/runners/models/__pycache__/openai_class.cpython-311.pyc +0 -0
  164. clarifai/runners/models/base_typed_model.py +238 -0
  165. clarifai/runners/models/model_builder.py +274 -10
  166. clarifai/runners/models/model_runner.py +93 -76
  167. clarifai/runners/models/model_upload.py +607 -0
  168. clarifai/runners/pipeline_steps/__pycache__/__init__.cpython-311.pyc +0 -0
  169. clarifai/runners/pipeline_steps/__pycache__/pipeline_step_builder.cpython-311.pyc +0 -0
  170. clarifai/runners/pipeline_steps/pipeline_step_builder.py +10 -1
  171. clarifai/runners/pipelines/__pycache__/__init__.cpython-311.pyc +0 -0
  172. clarifai/runners/pipelines/__pycache__/pipeline_builder.cpython-311.pyc +0 -0
  173. clarifai/runners/server.py +1 -1
  174. clarifai/runners/utils/__pycache__/__init__.cpython-311.pyc +0 -0
  175. clarifai/runners/utils/__pycache__/__init__.cpython-39.pyc +0 -0
  176. clarifai/runners/utils/__pycache__/code_script.cpython-311.pyc +0 -0
  177. clarifai/runners/utils/__pycache__/code_script.cpython-39.pyc +0 -0
  178. clarifai/runners/utils/__pycache__/const.cpython-311.pyc +0 -0
  179. clarifai/runners/utils/__pycache__/data_utils.cpython-311.pyc +0 -0
  180. clarifai/runners/utils/__pycache__/data_utils.cpython-39.pyc +0 -0
  181. clarifai/runners/utils/__pycache__/loader.cpython-311.pyc +0 -0
  182. clarifai/runners/utils/__pycache__/method_signatures.cpython-311.pyc +0 -0
  183. clarifai/runners/utils/__pycache__/model_utils.cpython-311.pyc +0 -0
  184. clarifai/runners/utils/__pycache__/openai_convertor.cpython-311.pyc +0 -0
  185. clarifai/runners/utils/__pycache__/pipeline_validation.cpython-311.pyc +0 -0
  186. clarifai/runners/utils/__pycache__/serializers.cpython-311.pyc +0 -0
  187. clarifai/runners/utils/__pycache__/url_fetcher.cpython-311.pyc +0 -0
  188. clarifai/runners/utils/data_handler.py +231 -0
  189. clarifai/runners/utils/data_types/__pycache__/__init__.cpython-311.pyc +0 -0
  190. clarifai/runners/utils/data_types/__pycache__/__init__.cpython-39.pyc +0 -0
  191. clarifai/runners/utils/data_types/__pycache__/data_types.cpython-311.pyc +0 -0
  192. clarifai/runners/utils/data_types/__pycache__/data_types.cpython-39.pyc +0 -0
  193. clarifai/runners/utils/data_types.py +471 -0
  194. clarifai/runners/utils/loader.py +24 -4
  195. clarifai/runners/utils/temp.py +59 -0
  196. clarifai/schema/__pycache__/search.cpython-311.pyc +0 -0
  197. clarifai/urls/__pycache__/helper.cpython-311.pyc +0 -0
  198. clarifai/urls/__pycache__/helper.cpython-39.pyc +0 -0
  199. clarifai/utils/__pycache__/__init__.cpython-311.pyc +0 -0
  200. clarifai/utils/__pycache__/__init__.cpython-39.pyc +0 -0
  201. clarifai/utils/__pycache__/cli.cpython-311.pyc +0 -0
  202. clarifai/utils/__pycache__/cli.cpython-39.pyc +0 -0
  203. clarifai/utils/__pycache__/config.cpython-311.pyc +0 -0
  204. clarifai/utils/__pycache__/config.cpython-39.pyc +0 -0
  205. clarifai/utils/__pycache__/constants.cpython-311.pyc +0 -0
  206. clarifai/utils/__pycache__/constants.cpython-39.pyc +0 -0
  207. clarifai/utils/__pycache__/logging.cpython-311.pyc +0 -0
  208. clarifai/utils/__pycache__/logging.cpython-39.pyc +0 -0
  209. clarifai/utils/__pycache__/misc.cpython-311.pyc +0 -0
  210. clarifai/utils/__pycache__/misc.cpython-39.pyc +0 -0
  211. clarifai/utils/__pycache__/model_train.cpython-311.pyc +0 -0
  212. clarifai/utils/__pycache__/protobuf.cpython-311.pyc +0 -0
  213. clarifai/utils/__pycache__/protobuf.cpython-39.pyc +0 -0
  214. clarifai/utils/__pycache__/secrets.cpython-311.pyc +0 -0
  215. clarifai/utils/evaluation/__pycache__/__init__.cpython-311.pyc +0 -0
  216. clarifai/utils/evaluation/__pycache__/helpers.cpython-311.pyc +0 -0
  217. clarifai/utils/evaluation/__pycache__/main.cpython-311.pyc +0 -0
  218. clarifai/utils/evaluation/__pycache__/testset_annotation_parser.cpython-311.pyc +0 -0
  219. clarifai/utils/misc.py +20 -0
  220. clarifai/utils/secrets.py +96 -1
  221. clarifai/workflows/__pycache__/__init__.cpython-311.pyc +0 -0
  222. clarifai/workflows/__pycache__/export.cpython-311.pyc +0 -0
  223. clarifai/workflows/__pycache__/utils.cpython-311.pyc +0 -0
  224. clarifai/workflows/__pycache__/validate.cpython-311.pyc +0 -0
  225. {clarifai-11.7.4.dist-info → clarifai-11.7.5rc1.dist-info}/METADATA +1 -1
  226. clarifai-11.7.5rc1.dist-info/RECORD +339 -0
  227. {clarifai-11.7.4.dist-info → clarifai-11.7.5rc1.dist-info}/WHEEL +1 -1
  228. clarifai-11.7.4.dist-info/RECORD +0 -129
  229. {clarifai-11.7.4.dist-info → clarifai-11.7.5rc1.dist-info}/entry_points.txt +0 -0
  230. {clarifai-11.7.4.dist-info → clarifai-11.7.5rc1.dist-info}/licenses/LICENSE +0 -0
  231. {clarifai-11.7.4.dist-info → clarifai-11.7.5rc1.dist-info}/top_level.txt +0 -0
clarifai/client/user.py CHANGED
@@ -533,6 +533,178 @@ class User(Lister, BaseClient):
533
533
  ]
534
534
  return f"Clarifai User Details: \n{', '.join(attribute_strings)}\n"
535
535
 
536
+ def get_secret(self, secret_id: str) -> dict:
537
+ """Returns a secret object if exists.
538
+
539
+ Args:
540
+ secret_id (str): The secret ID to interact with
541
+
542
+ Returns:
543
+ Dict: A dictionary containing information about the existing secret ID.
544
+
545
+ Example:
546
+ >>> from clarifai.client.user import User
547
+ >>> client = User(user_id="user_id")
548
+ >>> secret_info = client.get_secret(secret_id="secret_id")
549
+ """
550
+ request = service_pb2.GetSecretRequest(user_app_id=self.user_app_id, id=secret_id)
551
+ response = self._grpc_request(self.STUB.GetSecret, request)
552
+ if response.status.code != status_code_pb2.SUCCESS:
553
+ raise Exception(
554
+ f"""Error getting secret, are you sure this is a valid secret id {secret_id} at the user_id
555
+ {self.user_app_id.user_id}.
556
+ Error: {response.status.description}"""
557
+ )
558
+
559
+ dict_response = MessageToDict(response, preserving_proto_field_name=True)
560
+ kwargs = self.process_response_keys(dict_response["secret"], "secret")
561
+
562
+ return dict(auth=self.auth_helper, **kwargs)
563
+
564
+ def list_secrets(
565
+ self, page_no: int = None, per_page: int = None
566
+ ) -> Generator[dict, None, None]:
567
+ """List all secrets for the user
568
+
569
+ Args:
570
+ page_no (int): The page number to list.
571
+ per_page (int): The number of items per page.
572
+
573
+ Yields:
574
+ Dict: Dictionaries containing information about the secrets.
575
+
576
+ Example:
577
+ >>> from clarifai.client.user import User
578
+ >>> client = User(user_id="user_id")
579
+ >>> all_secrets = list(client.list_secrets())
580
+
581
+ Note:
582
+ Defaults to 16 per page if page_no is specified and per_page is not specified.
583
+ If both page_no and per_page are None, then lists all the resources.
584
+ """
585
+ request_data = dict(user_app_id=self.user_app_id)
586
+ all_secrets_info = self.list_pages_generator(
587
+ self.STUB.ListSecrets,
588
+ service_pb2.ListSecretsRequest,
589
+ request_data,
590
+ per_page=per_page,
591
+ page_no=page_no,
592
+ )
593
+ for secret_info in all_secrets_info:
594
+ yield dict(auth=self.auth_helper, **secret_info)
595
+
596
+ def create_secrets(self, secrets: List[Dict[str, Any]]) -> List[dict]:
597
+ """Creates secrets for the user.
598
+
599
+ Args:
600
+ secrets (List[Dict[str, Any]]): List of secret configurations to create.
601
+ Each secret dict can contain:
602
+ - id (str): The name/ID of the secret (required)
603
+ - value (str): The secret value (required)
604
+ - description (str): Optional description of the secret
605
+ - expires_at (str): Optional expiration timestamp
606
+
607
+ Returns:
608
+ List[Dict]: List of dictionaries containing information about the created secrets.
609
+
610
+ Example:
611
+ >>> from clarifai.client.user import User
612
+ >>> client = User(user_id="user_id")
613
+ >>> secrets = [{"id": "secret1", "value": "secret_value", "description": "My Secret"}]
614
+ >>> created_secrets = client.create_secrets(secrets)
615
+ """
616
+ assert isinstance(secrets, list), "secrets param should be a list"
617
+
618
+ # Convert dict secrets to protobuf Secret objects
619
+ secret_objects = []
620
+ for secret_config in secrets:
621
+ secret_objects.append(resources_pb2.Secret(**secret_config))
622
+
623
+ request = service_pb2.PostSecretsRequest(
624
+ user_app_id=self.user_app_id, secrets=secret_objects
625
+ )
626
+ response = self._grpc_request(self.STUB.PostSecrets, request)
627
+ if response.status.code != status_code_pb2.SUCCESS:
628
+ raise Exception(response.status)
629
+
630
+ self.logger.info(f"Secrets created successfully:\n{response.status}")
631
+
632
+ # Convert response to list of dictionaries
633
+ dict_response = MessageToDict(response, preserving_proto_field_name=True)
634
+ created_secrets = []
635
+ for secret in dict_response.get("secrets", []):
636
+ kwargs = self.process_response_keys(secret, "secret")
637
+ created_secrets.append(dict(auth=self.auth_helper, **kwargs))
638
+
639
+ return created_secrets
640
+
641
+ def patch_secrets(
642
+ self, secrets: List[Dict[str, Any]], action: str = 'overwrite'
643
+ ) -> List[dict]:
644
+ """Patches secrets for the user.
645
+
646
+ Args:
647
+ secrets (List[Dict[str, Any]]): List of secret configurations to patch.
648
+ Each secret dict should contain:
649
+ - id (str): The name/ID of the secret to patch (required)
650
+ - value (str): Optional new secret value
651
+ - description (str): Optional new description
652
+ - expires_at (str): Optional new expiration timestamp
653
+ action (str): The action to perform on the secrets (overwrite/remove).
654
+
655
+ Returns:
656
+ List[Dict]: List of dictionaries containing information about the patched secrets.
657
+
658
+ Example:
659
+ >>> from clarifai.client.user import User
660
+ >>> client = User(user_id="user_id")
661
+ >>> secrets = [{"id": "secret1", "description": "Updated Secret Description"}]
662
+ >>> patched_secrets = client.patch_secrets(secrets, action="overwrite")
663
+ """
664
+ assert isinstance(secrets, list), "secrets param should be a list"
665
+
666
+ # Convert dict secrets to protobuf Secret objects
667
+ secret_objects = []
668
+ for secret_config in secrets:
669
+ secret_objects.append(resources_pb2.Secret(**secret_config))
670
+
671
+ request = service_pb2.PatchSecretsRequest(
672
+ user_app_id=self.user_app_id, secret=secret_objects, action=action
673
+ )
674
+ response = self._grpc_request(self.STUB.PatchSecrets, request)
675
+ if response.status.code != status_code_pb2.SUCCESS:
676
+ raise Exception(response.status)
677
+
678
+ self.logger.info(f"Secrets patched successfully:\n{response.status}")
679
+
680
+ # Convert response to list of dictionaries
681
+ dict_response = MessageToDict(response, preserving_proto_field_name=True)
682
+ patched_secrets = []
683
+ for secret in dict_response.get("secrets", []):
684
+ kwargs = self.process_response_keys(secret, "secret")
685
+ patched_secrets.append(dict(auth=self.auth_helper, **kwargs))
686
+
687
+ return patched_secrets
688
+
689
+ def delete_secrets(self, secret_ids: List[str]) -> None:
690
+ """Deletes a list of secrets for the user.
691
+
692
+ Args:
693
+ secret_ids (List[str]): The secret IDs of the user to delete.
694
+
695
+ Example:
696
+ >>> from clarifai.client.user import User
697
+ >>> client = User(user_id="user_id")
698
+ >>> client.delete_secrets(secret_ids=["secret_id1", "secret_id2"])
699
+ """
700
+ assert isinstance(secret_ids, list), "secret_ids param should be a list"
701
+
702
+ request = service_pb2.DeleteSecretsRequest(user_app_id=self.user_app_id, ids=secret_ids)
703
+ response = self._grpc_request(self.STUB.DeleteSecrets, request)
704
+ if response.status.code != status_code_pb2.SUCCESS:
705
+ raise Exception(response.status)
706
+ self.logger.info("\nSecrets Deleted\n%s", response.status)
707
+
536
708
  def list_models(
537
709
  self,
538
710
  user_id: str = None,
@@ -0,0 +1,158 @@
1
+ # Clarifai Model Serving
2
+
3
+ ## Overview
4
+
5
+ Model Serving is a part of user journey at Clarifai offers a user-friendly interface for deploying your local model into production with Clarifai, featuring:
6
+
7
+ * A convenient command-line interface (CLI)
8
+ * Easy implementation and testing in Python
9
+ * No need for MLops expertise.
10
+
11
+ ## Quickstart Guide
12
+
13
+ Quick example for deploying a `text-to-text` model
14
+
15
+ ### Initialize a Clarifai model repository
16
+
17
+ Suppose your working directory name is `your_model_dir`. Then run
18
+
19
+ ```bash
20
+ $ clarifai create model --type text-to-text --working-dir your_model_dir
21
+ $ cd your_model_dir
22
+ ```
23
+
24
+ In `your_model_dir` folder you will see essential files for deployment process
25
+
26
+ ```bash
27
+ your_model_dir
28
+ ├── clarifai_config.yaml
29
+ ├── inference.py
30
+ ├── test.py
31
+ └── requirements.txt
32
+ ```
33
+
34
+ ### Implementation
35
+
36
+ Write your code in class `InferenceModel` which is an interface between your model and Clarifai server in `inference.py`, there are 2 functions you must implement:
37
+
38
+ * `__init__`: load your model checkpoint once.
39
+ * `predict`: make prediction, called everytime when you make request from API.
40
+
41
+ For example, a complete implementation of a hf text-generation model
42
+
43
+ ```python
44
+ import os
45
+ from typing import Dict, Union
46
+ from clarifai.models.model_serving.model_config import *
47
+
48
+ import torch
49
+ from transformers import AutoTokenizer
50
+ import transformers
51
+
52
+ class InferenceModel(TextToText):
53
+ """User model inference class."""
54
+
55
+ def __init__(self) -> None:
56
+ """
57
+ Load inference time artifacts that are called frequently .e.g. models, tokenizers, etc.
58
+ in this method so they are loaded only once for faster inference.
59
+ """
60
+ # current directory
61
+ self.base_path = os.path.dirname(__file__)
62
+ # where you save hf checkpoint in your working dir e.i. `your_model_dir`
63
+ model_path = os.path.join(self.base_path, "checkpoint")
64
+ self.tokenizer = AutoTokenizer.from_pretrained(model_path)
65
+ self.pipeline = transformers.pipeline(
66
+ "text-generation",
67
+ model=model_path,
68
+ torch_dtype=torch.float16,
69
+ device_map="auto",
70
+ )
71
+
72
+ def predict(self, input_data: list,
73
+ inference_parameters: Dict[str, Union[str, float, int]]) -> list:
74
+ """ Custom prediction function for `text-to-text` (also called as `text generation`) model.
75
+
76
+ Args:
77
+ input_data (List[str]): List of text
78
+ inference_parameters (Dict[str, Union[str, float, int]]): your inference parameters
79
+
80
+ Returns:
81
+ list of TextOutput
82
+
83
+ """
84
+ output_sequences = self.pipeline(
85
+ input_data,
86
+ eos_token_id=self.tokenizer.eos_token_id,
87
+ **inference_parameters)
88
+
89
+ # wrap outputs in Clarifai defined output
90
+ return [TextOutput(each[0]) for each in output_sequences]
91
+ ```
92
+
93
+ Update dependencies in `requirements.txt`
94
+
95
+ ```
96
+ clarifai
97
+ torch=2.1.1
98
+ transformers==4.36.2
99
+ accelerate==0.26.1
100
+ ```
101
+
102
+ ### Test (optional)
103
+
104
+ > NOTE: Running `test` is also involved in `build` and `upload` command.
105
+
106
+ Test and play with your implementation by executing `test.py`.
107
+
108
+ Install pytest
109
+
110
+ ```bash
111
+ $ pip install pytest
112
+ ```
113
+
114
+ Execute test
115
+
116
+ ```bash
117
+ $ pytest test.py
118
+ ```
119
+
120
+ ### Build
121
+
122
+ Prepare for deployment step. Run:
123
+
124
+ ```bash
125
+ $ clarifai build model
126
+ ```
127
+
128
+ You will obtain `*.clarifai` file, it's simply a zip having all nessecary files in it to get your model work on Clarifai platform.
129
+
130
+ `NOTE`: you need to upload your built file to cloud storage to get direct download `url` for next step
131
+
132
+ ### Deployment
133
+
134
+ Login to Clarifai
135
+
136
+ ```bash
137
+ $ clarifai login
138
+ Get your PAT from https://clarifai.com/settings/security and pass it here: <insert your pat here>
139
+ ```
140
+
141
+ Upload
142
+
143
+ ```bash
144
+ # upload built file directly
145
+ $ clarifai upload model <your-working-dir> --user-app <your_user_id>/<your_app_id> --id <your_model_id>
146
+ # or using direct download url of cloud storage
147
+ $ clarifai upload model --url <url> --user-app <your_user_id>/<your_app_id> --id <your_model_id>
148
+ ```
149
+
150
+ ## Learn More
151
+
152
+ * [Detail Instruction](./docs/concepts.md)
153
+ * [Examples](https://github.com/Clarifai/examples/tree/main/model_upload)
154
+ * [Initialize from example](./docs/cli.md)
155
+ * [CLI usage](./docs/cli.md)
156
+ * [Inference parameters](./docs/inference_parameters.md)
157
+ * [Model Types](./docs/model_types.md)
158
+ * [Dependencies](./docs/dependencies.md)
@@ -0,0 +1,14 @@
1
+ # Copyright 2023 Clarifai, Inc.
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ from .model_config import * # noqa
14
+ from .repo_build import * # noqa
@@ -0,0 +1,12 @@
1
+ # Copyright 2023 Clarifai, Inc.
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
@@ -0,0 +1,53 @@
1
+ from __future__ import annotations # isort: skip
2
+ import os
3
+ import shutil
4
+ import subprocess
5
+ from typing import Dict, Union
6
+
7
+ from ..constants import (CLARIFAI_EXAMPLES_REPO, CLARIFAI_EXAMPLES_REPO_PATH,
8
+ MODEL_UPLOAD_EXAMPLE_FOLDER)
9
+
10
+
11
+ def download_examples_repo(forced_download: bool = False):
12
+
13
+ def _pull():
14
+ subprocess.run(f"git clone {CLARIFAI_EXAMPLES_REPO} {CLARIFAI_EXAMPLES_REPO_PATH}", shell=True)
15
+
16
+ if not os.path.isdir(CLARIFAI_EXAMPLES_REPO_PATH):
17
+ print(f"Download examples to {CLARIFAI_EXAMPLES_REPO_PATH}")
18
+ _pull()
19
+ else:
20
+ if forced_download:
21
+
22
+ def _rm_dir_readonly(func, path, _):
23
+ import stat
24
+ os.chmod(path, stat.S_IWRITE)
25
+ func(path)
26
+
27
+ print("Removing old examples...")
28
+ shutil.rmtree(CLARIFAI_EXAMPLES_REPO_PATH, onerror=_rm_dir_readonly)
29
+ _pull()
30
+
31
+
32
+ def list_model_upload_examples(
33
+ forced_download: bool = False) -> Dict[str, tuple[str, Union[str, None]]]:
34
+ download_examples_repo(forced_download)
35
+ model_upload_folder = MODEL_UPLOAD_EXAMPLE_FOLDER
36
+ model_upload_path = os.path.join(CLARIFAI_EXAMPLES_REPO_PATH, model_upload_folder)
37
+ examples = {}
38
+ for model_type_ex in os.listdir(model_upload_path):
39
+ _folder = os.path.join(model_upload_path, model_type_ex)
40
+ if os.path.isdir(_folder):
41
+ _walk = list(os.walk(_folder))
42
+ if len(_walk) > 0:
43
+ _, model_names, _files = _walk[0]
44
+ readme = [item for item in _files if "readme" in item.lower()]
45
+ for name in model_names:
46
+ examples.update({
47
+ f"{model_type_ex}/{name}": [
48
+ os.path.join(_folder, name),
49
+ os.path.join(_folder, readme[0]) or None
50
+ ]
51
+ })
52
+
53
+ return examples
@@ -0,0 +1,14 @@
1
+ from abc import ABC, abstractmethod
2
+ from argparse import _SubParsersAction
3
+
4
+
5
+ class BaseClarifaiCli(ABC):
6
+
7
+ @staticmethod
8
+ @abstractmethod
9
+ def register(parser: _SubParsersAction):
10
+ raise NotImplementedError()
11
+
12
+ @abstractmethod
13
+ def run(self):
14
+ raise NotImplementedError()
@@ -0,0 +1,79 @@
1
+ # Copyright 2023 Clarifai, Inc.
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ """Commandline interface for model upload utils."""
14
+ import argparse
15
+ import os
16
+ import subprocess
17
+
18
+ from ..repo_build import RepositoryBuilder
19
+ from .base import BaseClarifaiCli
20
+
21
+
22
+ class BuildCli(BaseClarifaiCli):
23
+
24
+ @staticmethod
25
+ def register(parser: argparse._SubParsersAction):
26
+ parser = parser.add_parser("build", help="Build clarifai model for uploading")
27
+ sub_parser = parser.add_subparsers()
28
+
29
+ BuildModelSubCli.register(sub_parser)
30
+
31
+ parser.set_defaults(func=BuildCli)
32
+
33
+
34
+ class BuildModelSubCli(BaseClarifaiCli):
35
+
36
+ @staticmethod
37
+ def register(parser: argparse._SubParsersAction):
38
+ sub_parser = parser.add_parser("model", help="Build Clarifai model")
39
+ sub_parser.add_argument(
40
+ "path",
41
+ type=str,
42
+ nargs='?',
43
+ help="Path to working directory, default is current directory",
44
+ default=".")
45
+ sub_parser.add_argument(
46
+ "--out-path", type=str, required=False, help="Output path of built model", default=None)
47
+ sub_parser.add_argument(
48
+ "--name",
49
+ type=str,
50
+ required=False,
51
+ help="Name of built file, default is `clarifai_model_id` in config if set or `model`",
52
+ default=None)
53
+ sub_parser.add_argument(
54
+ "--no-test",
55
+ action="store_true",
56
+ help="Trigger this flag to skip testing before uploading")
57
+ sub_parser.set_defaults(func=BuildModelSubCli)
58
+
59
+ def __init__(self, args: argparse.Namespace) -> None:
60
+ self.path = args.path
61
+ self.no_test = args.no_test
62
+ self.test_path = os.path.join(self.path, "test.py")
63
+ self.output_path = args.out_path or self.path
64
+ self.serving_backend = "triton"
65
+ self.name = args.name
66
+
67
+ def run(self):
68
+
69
+ # Run test before uploading
70
+ if not self.no_test:
71
+ assert os.path.exists(
72
+ self.test_path), FileNotFoundError(f"Could not find `test.py` in {self.path}")
73
+ result = subprocess.run(f"pytest -s --log-level=INFO {self.test_path}", shell=True)
74
+ assert result.returncode == 0, "Test has failed. Please make sure no error exists in your code."
75
+
76
+ # build
77
+ print("Start building...")
78
+ RepositoryBuilder.build(
79
+ self.path, backend=self.serving_backend, output_dir=self.output_path, name=self.name)
@@ -0,0 +1,33 @@
1
+ from argparse import ArgumentParser
2
+
3
+ from .build import BuildCli
4
+ from .create import CreateCli
5
+ from .example_cli import ExampleCli
6
+ from .login import LoginCli
7
+ from .upload import UploadCli
8
+
9
+
10
+ def main():
11
+
12
+ parser = ArgumentParser("clarifai")
13
+ cmd_parser = parser.add_subparsers(help="Clarifai cli helpers")
14
+
15
+ UploadCli.register(cmd_parser)
16
+ CreateCli.register(cmd_parser)
17
+ LoginCli.register(cmd_parser)
18
+ ExampleCli.register(cmd_parser)
19
+ BuildCli.register(cmd_parser)
20
+
21
+ args = parser.parse_args()
22
+
23
+ if not hasattr(args, "func"):
24
+ parser.print_help()
25
+ exit(1)
26
+
27
+ # Run
28
+ service = args.func(args)
29
+ service.run()
30
+
31
+
32
+ if __name__ == "__main__":
33
+ main()