clarifai 10.0.1__py3-none-any.whl → 10.1.1__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 (83) hide show
  1. clarifai/client/app.py +23 -43
  2. clarifai/client/base.py +46 -4
  3. clarifai/client/dataset.py +85 -33
  4. clarifai/client/input.py +35 -7
  5. clarifai/client/model.py +192 -11
  6. clarifai/client/module.py +8 -6
  7. clarifai/client/runner.py +3 -1
  8. clarifai/client/search.py +6 -3
  9. clarifai/client/user.py +14 -12
  10. clarifai/client/workflow.py +8 -5
  11. clarifai/datasets/upload/features.py +3 -0
  12. clarifai/datasets/upload/image.py +57 -26
  13. clarifai/datasets/upload/loaders/README.md +3 -4
  14. clarifai/datasets/upload/loaders/xview_detection.py +9 -5
  15. clarifai/datasets/upload/utils.py +23 -7
  16. clarifai/models/model_serving/README.md +113 -121
  17. clarifai/models/model_serving/__init__.py +2 -0
  18. clarifai/models/model_serving/cli/_utils.py +53 -0
  19. clarifai/models/model_serving/cli/base.py +14 -0
  20. clarifai/models/model_serving/cli/build.py +79 -0
  21. clarifai/models/model_serving/cli/clarifai_clis.py +33 -0
  22. clarifai/models/model_serving/cli/create.py +171 -0
  23. clarifai/models/model_serving/cli/example_cli.py +34 -0
  24. clarifai/models/model_serving/cli/login.py +26 -0
  25. clarifai/models/model_serving/cli/upload.py +182 -0
  26. clarifai/models/model_serving/constants.py +20 -0
  27. clarifai/models/model_serving/docs/cli.md +150 -0
  28. clarifai/models/model_serving/docs/concepts.md +229 -0
  29. clarifai/models/model_serving/docs/dependencies.md +1 -1
  30. clarifai/models/model_serving/docs/inference_parameters.md +112 -107
  31. clarifai/models/model_serving/docs/model_types.md +16 -17
  32. clarifai/models/model_serving/model_config/__init__.py +4 -2
  33. clarifai/models/model_serving/model_config/base.py +369 -0
  34. clarifai/models/model_serving/model_config/config.py +219 -224
  35. clarifai/models/model_serving/model_config/inference_parameter.py +5 -0
  36. clarifai/models/model_serving/model_config/model_types_config/multimodal-embedder.yaml +25 -24
  37. clarifai/models/model_serving/model_config/model_types_config/text-classifier.yaml +19 -18
  38. clarifai/models/model_serving/model_config/model_types_config/text-embedder.yaml +20 -18
  39. clarifai/models/model_serving/model_config/model_types_config/text-to-image.yaml +19 -18
  40. clarifai/models/model_serving/model_config/model_types_config/text-to-text.yaml +19 -18
  41. clarifai/models/model_serving/model_config/model_types_config/visual-classifier.yaml +22 -18
  42. clarifai/models/model_serving/model_config/model_types_config/visual-detector.yaml +32 -28
  43. clarifai/models/model_serving/model_config/model_types_config/visual-embedder.yaml +19 -18
  44. clarifai/models/model_serving/model_config/model_types_config/visual-segmenter.yaml +19 -18
  45. clarifai/models/model_serving/{models → model_config}/output.py +8 -0
  46. clarifai/models/model_serving/model_config/triton/__init__.py +14 -0
  47. clarifai/models/model_serving/model_config/{serializer.py → triton/serializer.py} +3 -1
  48. clarifai/models/model_serving/model_config/triton/triton_config.py +182 -0
  49. clarifai/models/model_serving/{models/model_types.py → model_config/triton/wrappers.py} +4 -4
  50. clarifai/models/model_serving/{models → repo_build}/__init__.py +2 -0
  51. clarifai/models/model_serving/repo_build/build.py +198 -0
  52. clarifai/models/model_serving/repo_build/static_files/_requirements.txt +2 -0
  53. clarifai/models/model_serving/repo_build/static_files/base_test.py +169 -0
  54. clarifai/models/model_serving/repo_build/static_files/inference.py +26 -0
  55. clarifai/models/model_serving/repo_build/static_files/sample_clarifai_config.yaml +25 -0
  56. clarifai/models/model_serving/repo_build/static_files/test.py +40 -0
  57. clarifai/models/model_serving/{models/pb_model.py → repo_build/static_files/triton/model.py} +15 -14
  58. clarifai/models/model_serving/utils.py +21 -0
  59. clarifai/rag/rag.py +67 -23
  60. clarifai/rag/utils.py +21 -5
  61. clarifai/utils/evaluation/__init__.py +427 -0
  62. clarifai/utils/evaluation/helpers.py +522 -0
  63. clarifai/utils/logging.py +7 -0
  64. clarifai/utils/model_train.py +3 -1
  65. clarifai/versions.py +1 -1
  66. {clarifai-10.0.1.dist-info → clarifai-10.1.1.dist-info}/METADATA +58 -10
  67. clarifai-10.1.1.dist-info/RECORD +115 -0
  68. clarifai-10.1.1.dist-info/entry_points.txt +2 -0
  69. clarifai/datasets/upload/loaders/coco_segmentation.py +0 -98
  70. clarifai/models/model_serving/cli/deploy_cli.py +0 -123
  71. clarifai/models/model_serving/cli/model_zip.py +0 -61
  72. clarifai/models/model_serving/cli/repository.py +0 -89
  73. clarifai/models/model_serving/docs/custom_config.md +0 -33
  74. clarifai/models/model_serving/docs/output.md +0 -28
  75. clarifai/models/model_serving/models/default_test.py +0 -281
  76. clarifai/models/model_serving/models/inference.py +0 -50
  77. clarifai/models/model_serving/models/test.py +0 -64
  78. clarifai/models/model_serving/pb_model_repository.py +0 -108
  79. clarifai-10.0.1.dist-info/RECORD +0 -103
  80. clarifai-10.0.1.dist-info/entry_points.txt +0 -4
  81. {clarifai-10.0.1.dist-info → clarifai-10.1.1.dist-info}/LICENSE +0 -0
  82. {clarifai-10.0.1.dist-info → clarifai-10.1.1.dist-info}/WHEEL +0 -0
  83. {clarifai-10.0.1.dist-info → clarifai-10.1.1.dist-info}/top_level.txt +0 -0
clarifai/client/model.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import os
2
2
  import time
3
- from typing import Any, Dict, Generator, List
3
+ from typing import Any, Dict, Generator, List, Union
4
4
 
5
5
  import requests
6
6
  import yaml
@@ -32,6 +32,7 @@ class Model(Lister, BaseClient):
32
32
  model_version: Dict = {'id': ""},
33
33
  base_url: str = "https://api.clarifai.com",
34
34
  pat: str = None,
35
+ token: str = None,
35
36
  **kwargs):
36
37
  """Initializes a Model object.
37
38
 
@@ -41,6 +42,7 @@ class Model(Lister, BaseClient):
41
42
  model_version (dict): The Model Version to interact with.
42
43
  base_url (str): Base API url. Default "https://api.clarifai.com"
43
44
  pat (str): A personal access token for authentication. Can be set as env var CLARIFAI_PAT
45
+ token (str): A session token for authentication. Accepts either a session token or a pat. Can be set as env var CLARIFAI_SESSION_TOKEN
44
46
  **kwargs: Additional keyword arguments to be passed to the Model.
45
47
  """
46
48
  if url and model_id:
@@ -53,9 +55,10 @@ class Model(Lister, BaseClient):
53
55
  kwargs = {'user_id': user_id, 'app_id': app_id}
54
56
  self.kwargs = {**kwargs, 'id': model_id, 'model_version': model_version,}
55
57
  self.model_info = resources_pb2.Model(**self.kwargs)
56
- self.logger = get_logger(logger_level="INFO")
58
+ self.logger = get_logger(logger_level="INFO", name=__name__)
57
59
  self.training_params = {}
58
- BaseClient.__init__(self, user_id=self.user_id, app_id=self.app_id, base=base_url, pat=pat)
60
+ BaseClient.__init__(
61
+ self, user_id=self.user_id, app_id=self.app_id, base=base_url, pat=pat, token=token)
59
62
  Lister.__init__(self)
60
63
 
61
64
  def list_training_templates(self) -> List[str]:
@@ -212,6 +215,8 @@ class Model(Lister, BaseClient):
212
215
  >>> model_params = model.get_params(template='template', yaml_file='model_params.yaml')
213
216
  >>> model.train('model_params.yaml')
214
217
  """
218
+ if not self.model_info.model_type_id:
219
+ self.load_info()
215
220
  if self.model_info.model_type_id not in TRAINABLE_MODEL_TYPES:
216
221
  raise UserError(f"Model type {self.model_info.model_type_id} is not trainable")
217
222
  if not yaml_file and len(self.training_params) == 0:
@@ -222,8 +227,10 @@ class Model(Lister, BaseClient):
222
227
  params_dict = yaml.safe_load(file)
223
228
  else:
224
229
  params_dict = self.training_params
225
-
226
- train_dict = params_parser(params_dict)
230
+ #getting all the concepts for the model type
231
+ if self.model_info.model_type_id not in ["clusterer", "text-to-text"]:
232
+ concepts = self._list_concepts()
233
+ train_dict = params_parser(params_dict, concepts)
227
234
  request = service_pb2.PostModelVersionsRequest(
228
235
  user_app_id=self.user_app_id,
229
236
  model_id=self.id,
@@ -331,7 +338,7 @@ class Model(Lister, BaseClient):
331
338
  dict_response = MessageToDict(response, preserving_proto_field_name=True)
332
339
  kwargs = self.process_response_keys(dict_response['model'], 'model')
333
340
 
334
- return Model(base_url=self.base, pat=self.pat, **kwargs)
341
+ return Model(base_url=self.base, pat=self.pat, token=self.token, **kwargs)
335
342
 
336
343
  def list_versions(self, page_no: int = None,
337
344
  per_page: int = None) -> Generator['Model', None, None]:
@@ -373,11 +380,8 @@ class Model(Lister, BaseClient):
373
380
  del model_version_info['train_info']['dataset']['version']['metrics']
374
381
  except KeyError:
375
382
  pass
376
- yield Model(
377
- model_id=self.id,
378
- base_url=self.base,
379
- pat=self.pat,
380
- **dict(self.kwargs, model_version=model_version_info))
383
+ yield Model.from_auth_helper(
384
+ model_id=self.id, **dict(self.kwargs, model_version=model_version_info))
381
385
 
382
386
  def predict(self, inputs: List[Input], inference_params: Dict = {}, output_config: Dict = {}):
383
387
  """Predicts the model based on the given inputs.
@@ -548,6 +552,17 @@ class Model(Lister, BaseClient):
548
552
  resources_pb2.OutputInfo(
549
553
  output_config=resources_pb2.OutputConfig(**output_config), params=params))
550
554
 
555
+ def _list_concepts(self) -> List[str]:
556
+ """Lists all the concepts for the model type.
557
+
558
+ Returns:
559
+ concepts (List): List of concepts for the model type.
560
+ """
561
+ request_data = dict(user_app_id=self.user_app_id)
562
+ all_concepts_infos = self.list_pages_generator(self.STUB.ListConcepts,
563
+ service_pb2.ListConceptsRequest, request_data)
564
+ return [concept_info['concept_id'] for concept_info in all_concepts_infos]
565
+
551
566
  def load_info(self) -> None:
552
567
  """Loads the model info."""
553
568
  request = service_pb2.GetModelRequest(
@@ -576,3 +591,169 @@ class Model(Lister, BaseClient):
576
591
  if hasattr(self.model_info, param)
577
592
  ]
578
593
  return f"Model Details: \n{', '.join(attribute_strings)}\n"
594
+
595
+ def list_evaluations(self) -> resources_pb2.EvalMetrics:
596
+ """List all eval_metrics of current model version
597
+
598
+ Raises:
599
+ Exception: Failed to call API
600
+
601
+ Returns:
602
+ resources_pb2.EvalMetrics
603
+ """
604
+ assert self.model_info.model_version.id, "Model version is empty. Please provide `model_version` as arguments or with a URL as the format '{user_id}/{app_id}/models/{your_model_id}/model_version_id/{your_version_model_id}' when initializing."
605
+ request = service_pb2.ListModelVersionEvaluationsRequest(
606
+ user_app_id=self.user_app_id,
607
+ model_id=self.id,
608
+ model_version_id=self.model_info.model_version.id)
609
+ response = self._grpc_request(self.STUB.ListModelVersionEvaluations, request)
610
+
611
+ if response.status.code != status_code_pb2.SUCCESS:
612
+ raise Exception(response.status)
613
+
614
+ return response.eval_metrics
615
+
616
+ def evaluate(self,
617
+ dataset_id: str,
618
+ dataset_app_id: str = None,
619
+ dataset_user_id: str = None,
620
+ eval_id: str = None,
621
+ extended_metrics: dict = None,
622
+ eval_info: dict = None) -> resources_pb2.EvalMetrics:
623
+ """ Run evaluation
624
+
625
+ Args:
626
+ dataset_id (str): Dataset Id.
627
+ dataset_app_id (str): App ID for cross app evaluation, leave it as None to use Model App ID. Default is None.
628
+ dataset_user_id (str): User ID for cross app evaluation, leave it as None to use Model User ID. Default is None.
629
+ eval_id (str): Specific ID for the evaluation. You must specify this parameter to either overwrite the result with the dataset ID or format your evaluation in an informative manner. If you don't, it will use random ID from system. Default is None.
630
+ extended_metrics (dict): user custom metrics result. Default is None.
631
+ eval_info (dict): custom eval info. Default is empty dict.
632
+
633
+ Return
634
+ eval_metrics
635
+
636
+ """
637
+ assert self.model_info.model_version.id, "Model version is empty. Please provide `model_version` as arguments or with a URL as the format '{user_id}/{app_id}/models/{your_model_id}/model_version_id/{your_version_model_id}' when initializing."
638
+ metrics = None
639
+ if isinstance(extended_metrics, dict):
640
+ metrics = Struct()
641
+ metrics.update(extended_metrics)
642
+ metrics = resources_pb2.ExtendedMetrics(user_metrics=metrics)
643
+
644
+ eval_info_params = None
645
+ if isinstance(eval_info, dict):
646
+ eval_info_params = Struct()
647
+ eval_info_params.update(eval_info)
648
+ eval_info_params = resources_pb2.EvalInfo(params=eval_info_params)
649
+
650
+ eval_metric = resources_pb2.EvalMetrics(
651
+ id=eval_id,
652
+ model=resources_pb2.Model(
653
+ id=self.id,
654
+ app_id=self.auth_helper.app_id,
655
+ user_id=self.auth_helper.user_id,
656
+ model_version=resources_pb2.ModelVersion(id=self.model_info.model_version.id),
657
+ ),
658
+ extended_metrics=metrics,
659
+ ground_truth_dataset=resources_pb2.Dataset(
660
+ id=dataset_id,
661
+ app_id=dataset_app_id or self.auth_helper.app_id,
662
+ user_id=dataset_user_id or self.auth_helper.user_id,
663
+ ),
664
+ eval_info=eval_info_params,
665
+ )
666
+ request = service_pb2.PostEvaluationsRequest(
667
+ user_app_id=self.user_app_id,
668
+ eval_metrics=[eval_metric],
669
+ )
670
+ response = self._grpc_request(self.STUB.PostEvaluations, request)
671
+ if response.status.code != status_code_pb2.SUCCESS:
672
+ raise Exception(response.status)
673
+ self.logger.info(
674
+ "\nModel evaluation in progress. Kindly allow a few minutes for completion. Processing time may vary based on the model and dataset sizes."
675
+ )
676
+
677
+ return response.eval_metrics
678
+
679
+ def get_eval_by_id(
680
+ self,
681
+ eval_id: str,
682
+ label_counts=False,
683
+ test_set=False,
684
+ binary_metrics=False,
685
+ confusion_matrix=False,
686
+ metrics_by_class=False,
687
+ metrics_by_area=False,
688
+ ) -> resources_pb2.EvalMetrics:
689
+ """Get detail eval_metrics by eval_id with extra metric fields
690
+
691
+ Args:
692
+ eval_id (str): eval id
693
+ label_counts (bool, optional): Set True to get label counts. Defaults to False.
694
+ test_set (bool, optional): Set True to get test set. Defaults to False.
695
+ binary_metrics (bool, optional): Set True to get binary metric. Defaults to False.
696
+ confusion_matrix (bool, optional): Set True to get confusion matrix. Defaults to False.
697
+ metrics_by_class (bool, optional): Set True to get metrics by class. Defaults to False.
698
+ metrics_by_area (bool, optional): Set True to get metrics by area. Defaults to False.
699
+
700
+ Raises:
701
+ Exception: Failed to call API
702
+
703
+ Returns:
704
+ resources_pb2.EvalMetrics: eval_metrics
705
+ """
706
+ request = service_pb2.GetEvaluationRequest(
707
+ user_app_id=self.user_app_id,
708
+ evaluation_id=eval_id,
709
+ fields=resources_pb2.FieldsValue(
710
+ label_counts=label_counts,
711
+ test_set=test_set,
712
+ binary_metrics=binary_metrics,
713
+ confusion_matrix=confusion_matrix,
714
+ metrics_by_class=metrics_by_class,
715
+ metrics_by_area=metrics_by_area,
716
+ ))
717
+ response = self._grpc_request(self.STUB.GetEvaluation, request)
718
+
719
+ if response.status.code != status_code_pb2.SUCCESS:
720
+ raise Exception(response.status)
721
+
722
+ return response.eval_metrics
723
+
724
+ def get_latest_eval(self,
725
+ label_counts=False,
726
+ test_set=False,
727
+ binary_metrics=False,
728
+ confusion_matrix=False,
729
+ metrics_by_class=False,
730
+ metrics_by_area=False) -> Union[resources_pb2.EvalMetrics, None]:
731
+ """
732
+ Run `get_eval_by_id` method with latest `eval_id`
733
+
734
+ Args:
735
+ label_counts (bool, optional): Set True to get label counts. Defaults to False.
736
+ test_set (bool, optional): Set True to get test set. Defaults to False.
737
+ binary_metrics (bool, optional): Set True to get binary metric. Defaults to False.
738
+ confusion_matrix (bool, optional): Set True to get confusion matrix. Defaults to False.
739
+ metrics_by_class (bool, optional): Set True to get metrics by class. Defaults to False.
740
+ metrics_by_area (bool, optional): Set True to get metrics by area. Defaults to False.
741
+
742
+ Returns:
743
+ eval_metric if model is evaluated otherwise None.
744
+
745
+ """
746
+
747
+ _latest = self.list_evaluations()[0]
748
+ result = None
749
+ if _latest.status.code == status_code_pb2.MODEL_EVALUATED:
750
+ result = self.get_eval_by_id(
751
+ eval_id=_latest.id,
752
+ label_counts=label_counts,
753
+ test_set=test_set,
754
+ binary_metrics=binary_metrics,
755
+ confusion_matrix=confusion_matrix,
756
+ metrics_by_class=metrics_by_class,
757
+ metrics_by_area=metrics_by_area)
758
+
759
+ return result
clarifai/client/module.py CHANGED
@@ -18,6 +18,7 @@ class Module(Lister, BaseClient):
18
18
  module_version: Dict = {'id': ""},
19
19
  base_url: str = "https://api.clarifai.com",
20
20
  pat: str = None,
21
+ token: str = None,
21
22
  **kwargs):
22
23
  """Initializes a Module object.
23
24
 
@@ -26,7 +27,8 @@ class Module(Lister, BaseClient):
26
27
  module_id (str): The Module ID to interact with.
27
28
  module_version (dict): The Module Version to interact with.
28
29
  base_url (str): Base API url. Default "https://api.clarifai.com"
29
- pat (str): A personal access token for authentication. Can be set as env var CLARIFAI_PAT
30
+ pat (str): A personal access token for authentication. Can be set as env var CLARIFAI_PAT.
31
+ token (str): A session token for authentication. Accepts either a session token or a pat. Can be set as env var CLARIFAI_SESSION_TOKEN.
30
32
  **kwargs: Additional keyword arguments to be passed to the Module.
31
33
  """
32
34
  if url and module_id:
@@ -40,8 +42,9 @@ class Module(Lister, BaseClient):
40
42
 
41
43
  self.kwargs = {**kwargs, 'id': module_id, 'module_version': module_version}
42
44
  self.module_info = resources_pb2.Module(**self.kwargs)
43
- self.logger = get_logger(logger_level="INFO")
44
- BaseClient.__init__(self, user_id=self.user_id, app_id=self.app_id, base=base_url, pat=pat)
45
+ self.logger = get_logger(logger_level="INFO", name=__name__)
46
+ BaseClient.__init__(
47
+ self, user_id=self.user_id, app_id=self.app_id, base=base_url, pat=pat, token=token)
45
48
  Lister.__init__(self)
46
49
 
47
50
  def list_versions(self, page_no: int = None,
@@ -78,10 +81,9 @@ class Module(Lister, BaseClient):
78
81
  for module_version_info in all_module_versions_info:
79
82
  module_version_info['id'] = module_version_info['module_version_id']
80
83
  del module_version_info['module_version_id']
81
- yield Module(
84
+ yield Module.from_auth_helper(
85
+ self.auth_helper,
82
86
  module_id=self.id,
83
- base_url=self.base,
84
- pat=self.pat,
85
87
  **dict(self.kwargs, module_version=module_version_info))
86
88
 
87
89
  def __getattr__(self, name):
clarifai/client/runner.py CHANGED
@@ -39,6 +39,7 @@ class Runner(BaseClient):
39
39
  check_runner_exists: bool = True,
40
40
  base_url: str = "https://api.clarifai.com",
41
41
  pat: str = None,
42
+ token: str = None,
42
43
  num_parallel_polls: int = 4,
43
44
  **kwargs) -> None:
44
45
  """
@@ -47,6 +48,7 @@ class Runner(BaseClient):
47
48
  user_id (str): Clarifai User ID
48
49
  base_url (str): Base API url. Default "https://api.clarifai.com"
49
50
  pat (str): A personal access token for authentication. Can be set as env var CLARIFAI_PAT
51
+ 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
52
  num_parallel_polls (int): the max number of threads for parallel run loops to be fetching work from
51
53
  """
52
54
  user_id = user_id or os.environ.get("CLARIFAI_USER_ID", "")
@@ -60,7 +62,7 @@ class Runner(BaseClient):
60
62
  self.kwargs = {**kwargs, 'id': runner_id, 'user_id': user_id}
61
63
  self.runner_info = resources_pb2.Runner(**self.kwargs)
62
64
  self.num_parallel_polls = min(10, num_parallel_polls)
63
- BaseClient.__init__(self, user_id=self.user_id, app_id="", base=base_url, pat=pat)
65
+ BaseClient.__init__(self, user_id=self.user_id, app_id="", base=base_url, pat=pat, token=token)
64
66
 
65
67
  # Check that the runner exists.
66
68
  if check_runner_exists:
clarifai/client/search.py CHANGED
@@ -23,7 +23,8 @@ class Search(Lister, BaseClient):
23
23
  top_k: int = DEFAULT_TOP_K,
24
24
  metric: str = DEFAULT_SEARCH_METRIC,
25
25
  base_url: str = "https://api.clarifai.com",
26
- pat: str = None):
26
+ pat: str = None,
27
+ token: str = None):
27
28
  """Initialize the Search object.
28
29
 
29
30
  Args:
@@ -33,6 +34,7 @@ class Search(Lister, BaseClient):
33
34
  metric (str, optional): Similarity metric (either 'cosine' or 'euclidean'). Defaults to 'cosine'.
34
35
  base_url (str, optional): Base API url. Defaults to "https://api.clarifai.com".
35
36
  pat (str, optional): A personal access token for authentication. Can be set as env var CLARIFAI_PAT
37
+ token (str): A session token for authentication. Accepts either a session token or a pat. Can be set as env var CLARIFAI_SESSION_TOKEN
36
38
 
37
39
  Raises:
38
40
  UserError: If the metric is not 'cosine' or 'euclidean'.
@@ -46,9 +48,10 @@ class Search(Lister, BaseClient):
46
48
  self.data_proto = resources_pb2.Data()
47
49
  self.top_k = top_k
48
50
 
49
- self.inputs = Inputs(user_id=self.user_id, app_id=self.app_id, pat=pat)
51
+ self.inputs = Inputs(user_id=self.user_id, app_id=self.app_id, pat=pat, token=token)
50
52
  self.rank_filter_schema = get_schema()
51
- BaseClient.__init__(self, user_id=self.user_id, app_id=self.app_id, base=base_url, pat=pat)
53
+ BaseClient.__init__(
54
+ self, user_id=self.user_id, app_id=self.app_id, base=base_url, pat=pat, token=token)
52
55
  Lister.__init__(self, page_size=1000)
53
56
 
54
57
  def _get_annot_proto(self, **kwargs):
clarifai/client/user.py CHANGED
@@ -19,6 +19,7 @@ class User(Lister, BaseClient):
19
19
  user_id: str = None,
20
20
  base_url: str = "https://api.clarifai.com",
21
21
  pat: str = None,
22
+ token: str = None,
22
23
  **kwargs):
23
24
  """Initializes an User object.
24
25
 
@@ -26,12 +27,13 @@ class User(Lister, BaseClient):
26
27
  user_id (str): The user ID for the user to interact with.
27
28
  base_url (str): Base API url. Default "https://api.clarifai.com"
28
29
  pat (str): A personal access token for authentication. Can be set as env var CLARIFAI_PAT
30
+ token (str): A session token for authentication. Accepts either a session token or a pat. Can be set as env var CLARIFAI_SESSION_TOKEN
29
31
  **kwargs: Additional keyword arguments to be passed to the User.
30
32
  """
31
33
  self.kwargs = {**kwargs, 'id': user_id}
32
34
  self.user_info = resources_pb2.User(**self.kwargs)
33
35
  self.logger = get_logger(logger_level="INFO", name=__name__)
34
- BaseClient.__init__(self, user_id=self.id, app_id="", base=base_url, pat=pat)
36
+ BaseClient.__init__(self, user_id=self.id, app_id="", base=base_url, pat=pat, token=token)
35
37
  Lister.__init__(self)
36
38
 
37
39
  def list_apps(self, filter_by: Dict[str, Any] = {}, page_no: int = None,
@@ -62,7 +64,9 @@ class User(Lister, BaseClient):
62
64
  per_page=per_page,
63
65
  page_no=page_no)
64
66
  for app_info in all_apps_info:
65
- yield App(base_url=self.base, pat=self.pat, **app_info)
67
+ yield App.from_auth_helper(
68
+ self.auth_helper,
69
+ **app_info) #(base_url=self.base, pat=self.pat, token=self.token, **app_info)
66
70
 
67
71
  def list_runners(self, filter_by: Dict[str, Any] = {}, page_no: int = None,
68
72
  per_page: int = None) -> Generator[Runner, None, None]:
@@ -94,7 +98,8 @@ class User(Lister, BaseClient):
94
98
  page_no=page_no)
95
99
 
96
100
  for runner_info in all_runners_info:
97
- yield Runner(check_runner_exists=False, base_url=self.base, pat=self.pat, **runner_info)
101
+ yield Runner.from_auth_helper(
102
+ auth=self.auth_helper, check_runner_exists=False, **runner_info)
98
103
 
99
104
  def create_app(self, app_id: str, base_workflow: str = 'Empty', **kwargs) -> App:
100
105
  """Creates an app for the user.
@@ -120,8 +125,7 @@ class User(Lister, BaseClient):
120
125
  if response.status.code != status_code_pb2.SUCCESS:
121
126
  raise Exception(response.status)
122
127
  self.logger.info("\nApp created\n%s", response.status)
123
- kwargs.update({'user_id': self.id, 'base_url': self.base, 'pat': self.pat})
124
- return App(app_id=app_id, **kwargs)
128
+ return App.from_auth_helper(auth=self.auth_helper, app_id=app_id)
125
129
 
126
130
  def create_runner(self, runner_id: str, labels: List[str], description: str) -> Runner:
127
131
  """Create a runner
@@ -151,14 +155,13 @@ class User(Lister, BaseClient):
151
155
  raise Exception(response.status)
152
156
  self.logger.info("\nRunner created\n%s", response.status)
153
157
 
154
- return Runner(
158
+ return Runner.from_auth_helper(
159
+ auth=self.auth_helper,
155
160
  runner_id=runner_id,
156
161
  user_id=self.id,
157
162
  labels=labels,
158
163
  description=description,
159
- check_runner_exists=False,
160
- base_url=self.base,
161
- pat=self.pat)
164
+ check_runner_exists=False)
162
165
 
163
166
  def app(self, app_id: str, **kwargs) -> App:
164
167
  """Returns an App object for the specified app ID.
@@ -181,8 +184,7 @@ class User(Lister, BaseClient):
181
184
  raise Exception(response.status)
182
185
 
183
186
  kwargs['user_id'] = self.id
184
- kwargs.update({'base_url': self.base, 'pat': self.pat})
185
- return App(app_id=app_id, **kwargs)
187
+ return App.from_auth_helper(auth=self.auth_helper, app_id=app_id, **kwargs)
186
188
 
187
189
  def runner(self, runner_id: str) -> Runner:
188
190
  """Returns a Runner object if exists.
@@ -210,7 +212,7 @@ class User(Lister, BaseClient):
210
212
  kwargs = self.process_response_keys(dict_response[list(dict_response.keys())[1]],
211
213
  list(dict_response.keys())[1])
212
214
 
213
- return Runner(check_runner_exists=False, base_url=self.base, pat=self.pat, **kwargs)
215
+ return Runner.from_auth_helper(self.auth_helper, check_runner_exists=False, **kwargs)
214
216
 
215
217
  def delete_app(self, app_id: str) -> None:
216
218
  """Deletes an app for the user.
@@ -27,6 +27,7 @@ class Workflow(Lister, BaseClient):
27
27
  output_config: Dict = {'min_value': 0},
28
28
  base_url: str = "https://api.clarifai.com",
29
29
  pat: str = None,
30
+ token: str = None,
30
31
  **kwargs):
31
32
  """Initializes a Workflow object.
32
33
 
@@ -40,6 +41,8 @@ class Workflow(Lister, BaseClient):
40
41
  select_concepts (list[Concept]): The concepts to select.
41
42
  sample_ms (int): The number of milliseconds to sample.
42
43
  base_url (str): Base API url. Default "https://api.clarifai.com"
44
+ pat (str): A personal access token for authentication. Can be set as env var CLARIFAI_PAT
45
+ token (str): A session token for authentication. Accepts either a session token or a pat. Can be set as env var CLARIFAI_SESSION_TOKEN
43
46
  **kwargs: Additional keyword arguments to be passed to the Workflow.
44
47
  """
45
48
  if url and workflow_id:
@@ -54,8 +57,9 @@ class Workflow(Lister, BaseClient):
54
57
  self.kwargs = {**kwargs, 'id': workflow_id, 'version': workflow_version}
55
58
  self.output_config = output_config
56
59
  self.workflow_info = resources_pb2.Workflow(**self.kwargs)
57
- self.logger = get_logger(logger_level="INFO")
58
- BaseClient.__init__(self, user_id=self.user_id, app_id=self.app_id, base=base_url, pat=pat)
60
+ self.logger = get_logger(logger_level="INFO", name=__name__)
61
+ BaseClient.__init__(
62
+ self, user_id=self.user_id, app_id=self.app_id, base=base_url, pat=pat, token=token)
59
63
  Lister.__init__(self)
60
64
 
61
65
  def predict(self, inputs: List[Input], workflow_state_id: str = None):
@@ -206,10 +210,9 @@ class Workflow(Lister, BaseClient):
206
210
  for workflow_version_info in all_workflow_versions_info:
207
211
  workflow_version_info['id'] = workflow_version_info['workflow_version_id']
208
212
  del workflow_version_info['workflow_version_id']
209
- yield Workflow(
213
+ yield Workflow.from_auth_helper(
214
+ auth=self.auth_helper,
210
215
  workflow_id=self.id,
211
- base_url=self.base,
212
- pat=self.pat,
213
216
  **dict(self.kwargs, version=workflow_version_info))
214
217
 
215
218
  def export(self, out_path: str):
@@ -20,6 +20,7 @@ class VisualClassificationFeatures:
20
20
  geo_info: Optional[List[float]] = None #[Longitude, Latitude]
21
21
  id: Optional[int] = None # image_id
22
22
  metadata: Optional[dict] = None
23
+ image_bytes: Optional[bytes] = None
23
24
 
24
25
 
25
26
  @dataclass
@@ -31,6 +32,7 @@ class VisualDetectionFeatures:
31
32
  geo_info: Optional[List[float]] = None #[Longitude, Latitude]
32
33
  id: Optional[int] = None # image_id
33
34
  metadata: Optional[dict] = None
35
+ image_bytes: Optional[bytes] = None
34
36
 
35
37
 
36
38
  @dataclass
@@ -42,3 +44,4 @@ class VisualSegmentationFeatures:
42
44
  geo_info: Optional[List[float]] = None #[Longitude, Latitude]
43
45
  id: Optional[int] = None # image_id
44
46
  metadata: Optional[dict] = None
47
+ image_bytes: Optional[bytes] = None
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import uuid
2
3
  from concurrent.futures import ThreadPoolExecutor
3
4
  from typing import List, Tuple, Type
4
5
 
@@ -31,22 +32,34 @@ class VisualClassificationDataset(ClarifaiDataset):
31
32
  image_path = data_item.image_path
32
33
  labels = data_item.labels if isinstance(data_item.labels,
33
34
  list) else [data_item.labels] # clarifai concept
34
- input_id = f"{self.dataset_id}-{id}" if data_item.id is None else f"{self.dataset_id}-{str(data_item.id)}"
35
+ input_id = f"{self.dataset_id}-{uuid.uuid4().hex[:8]}" if data_item.id is None else f"{self.dataset_id}-{str(data_item.id)}"
35
36
  geo_info = data_item.geo_info
36
37
  if data_item.metadata is not None:
37
38
  metadata.update(data_item.metadata)
38
- else:
39
+ elif image_path is not None:
39
40
  metadata.update({"filename": os.path.basename(image_path)})
41
+ else:
42
+ metadata = None
40
43
 
41
44
  self.all_input_ids[id] = input_id
42
- input_protos.append(
43
- Inputs.get_input_from_file(
44
- input_id=input_id,
45
- image_file=image_path,
46
- dataset_id=self.dataset_id,
47
- labels=labels,
48
- geo_info=geo_info,
49
- metadata=metadata))
45
+ if data_item.image_bytes is not None:
46
+ input_protos.append(
47
+ Inputs.get_input_from_bytes(
48
+ input_id=input_id,
49
+ image_bytes=data_item.image_bytes,
50
+ dataset_id=self.dataset_id,
51
+ labels=labels,
52
+ geo_info=geo_info,
53
+ metadata=metadata))
54
+ else:
55
+ input_protos.append(
56
+ Inputs.get_input_from_file(
57
+ input_id=input_id,
58
+ image_file=image_path,
59
+ dataset_id=self.dataset_id,
60
+ labels=labels,
61
+ geo_info=geo_info,
62
+ metadata=metadata))
50
63
 
51
64
  with ThreadPoolExecutor(max_workers=4) as executor:
52
65
  futures = [executor.submit(process_data_item, id) for id in batch_input_ids]
@@ -79,7 +92,7 @@ class VisualDetectionDataset(ClarifaiDataset):
79
92
  image = data_item.image_path
80
93
  labels = data_item.labels # list:[l1,...,ln]
81
94
  bboxes = data_item.bboxes # [[xmin,ymin,xmax,ymax],...,[xmin,ymin,xmax,ymax]]
82
- input_id = f"{self.dataset_id}-{id}" if data_item.id is None else f"{self.dataset_id}-{str(data_item.id)}"
95
+ input_id = f"{self.dataset_id}-{uuid.uuid4().hex[:8]}" if data_item.id is None else f"{self.dataset_id}-{str(data_item.id)}"
83
96
  if data_item.metadata is not None:
84
97
  metadata.update(data_item.metadata)
85
98
  else:
@@ -87,13 +100,22 @@ class VisualDetectionDataset(ClarifaiDataset):
87
100
  geo_info = data_item.geo_info
88
101
 
89
102
  self.all_input_ids[id] = input_id
90
- input_protos.append(
91
- Inputs.get_input_from_file(
92
- input_id=input_id,
93
- image_file=image,
94
- dataset_id=self.dataset_id,
95
- geo_info=geo_info,
96
- metadata=metadata))
103
+ if data_item.image_bytes is not None:
104
+ input_protos.append(
105
+ Inputs.get_input_from_bytes(
106
+ input_id=input_id,
107
+ image_bytes=data_item.image_bytes,
108
+ dataset_id=self.dataset_id,
109
+ geo_info=geo_info,
110
+ metadata=metadata))
111
+ else:
112
+ input_protos.append(
113
+ Inputs.get_input_from_file(
114
+ input_id=input_id,
115
+ image_file=image,
116
+ dataset_id=self.dataset_id,
117
+ geo_info=geo_info,
118
+ metadata=metadata))
97
119
  # iter over bboxes and labels
98
120
  # one id could have more than one bbox and label
99
121
  for i in range(len(bboxes)):
@@ -131,7 +153,7 @@ class VisualSegmentationDataset(ClarifaiDataset):
131
153
  image = data_item.image_path
132
154
  labels = data_item.labels
133
155
  _polygons = data_item.polygons # list of polygons: [[[x,y],...,[x,y]],...]
134
- input_id = f"{self.dataset_id}-{id}" if data_item.id is None else f"{self.dataset_id}-{str(data_item.id)}"
156
+ input_id = f"{self.dataset_id}-{uuid.uuid4().hex[:8]}" if data_item.id is None else f"{self.dataset_id}-{str(data_item.id)}"
135
157
  if data_item.metadata is not None:
136
158
  metadata.update(data_item.metadata)
137
159
  else:
@@ -139,13 +161,22 @@ class VisualSegmentationDataset(ClarifaiDataset):
139
161
  geo_info = data_item.geo_info
140
162
 
141
163
  self.all_input_ids[id] = input_id
142
- input_protos.append(
143
- Inputs.get_input_from_file(
144
- input_id=input_id,
145
- image_file=image,
146
- dataset_id=self.dataset_id,
147
- geo_info=geo_info,
148
- metadata=metadata))
164
+ if data_item.image_bytes is not None:
165
+ input_protos.append(
166
+ Inputs.get_input_from_bytes(
167
+ input_id=input_id,
168
+ image_bytes=data_item.image_bytes,
169
+ dataset_id=self.dataset_id,
170
+ geo_info=geo_info,
171
+ metadata=metadata))
172
+ else:
173
+ input_protos.append(
174
+ Inputs.get_input_from_file(
175
+ input_id=input_id,
176
+ image_file=image,
177
+ dataset_id=self.dataset_id,
178
+ geo_info=geo_info,
179
+ metadata=metadata))
149
180
 
150
181
  ## Iterate over each masked image and create a proto for upload to clarifai
151
182
  ## The length of masks/polygons-list and labels must be equal
@@ -8,15 +8,15 @@ If a dataset module exists in the zoo, uploading the specific dataset can be eas
8
8
 
9
9
  ```python
10
10
  from clarifai.client.app import App
11
- from clarifai.datasets.upload.loaders.coco_segmentation import COCOSegmentationDataLoader
11
+ from clarifai.datasets.upload.loaders.coco_detection import COCODetectionDataLoader
12
12
 
13
13
  app = App(app_id="", user_id="")
14
14
  # Create a dataset in Clarifai App
15
15
  dataset = app.create_dataset(dataset_id="")
16
16
  # instantiate dataloader object
17
- coco_seg_dataloader = COCOSegmentationDataLoader(images_dir="", label_filepath="")
17
+ coco_det_dataloader = COCODetectionDataLoader(images_dir="", label_filepath="")
18
18
  # execute data upload to Clarifai app dataset
19
- dataset.upload_dataset(dataloader=coco_seg_dataloader)
19
+ dataset.upload_dataset(dataloader=coco_det_dataloader)
20
20
  ```
21
21
 
22
22
  ## Dataset Loaders
@@ -24,7 +24,6 @@ dataset.upload_dataset(dataloader=coco_seg_dataloader)
24
24
  | dataset name | task | module name (.py)
25
25
  | --- | --- | ---
26
26
  | [COCO 2017](https://cocodataset.org/#download) | Detection | `coco_detection` |
27
- | | Segmentation | `coco_segmentation` |
28
27
  | | Captions | `coco_captions` |
29
28
  |[xVIEW](http://xviewdataset.org/) | Detection | `xview_detection` |
30
29
  | [ImageNet](https://www.image-net.org/) | Classification | `imagenet_classification` |