clarifai 10.2.1__py3-none-any.whl → 10.3.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.
clarifai/client/module.py CHANGED
@@ -19,6 +19,7 @@ class Module(Lister, BaseClient):
19
19
  base_url: str = "https://api.clarifai.com",
20
20
  pat: str = None,
21
21
  token: str = None,
22
+ root_certificates_path: str = None,
22
23
  **kwargs):
23
24
  """Initializes a Module object.
24
25
 
@@ -29,6 +30,7 @@ class Module(Lister, BaseClient):
29
30
  base_url (str): Base API url. Default "https://api.clarifai.com"
30
31
  pat (str): A personal access token for authentication. Can be set as env var CLARIFAI_PAT.
31
32
  token (str): A session token for authentication. Accepts either a session token or a pat. Can be set as env var CLARIFAI_SESSION_TOKEN.
33
+ root_certificates_path (str): Path to the SSL root certificates file, used to establish secure gRPC connections.
32
34
  **kwargs: Additional keyword arguments to be passed to the Module.
33
35
  """
34
36
  if url and module_id:
@@ -44,7 +46,13 @@ class Module(Lister, BaseClient):
44
46
  self.module_info = resources_pb2.Module(**self.kwargs)
45
47
  self.logger = get_logger(logger_level="INFO", name=__name__)
46
48
  BaseClient.__init__(
47
- self, user_id=self.user_id, app_id=self.app_id, base=base_url, pat=pat, token=token)
49
+ self,
50
+ user_id=self.user_id,
51
+ app_id=self.app_id,
52
+ base=base_url,
53
+ pat=pat,
54
+ token=token,
55
+ root_certificates_path=root_certificates_path)
48
56
  Lister.__init__(self)
49
57
 
50
58
  def list_versions(self, page_no: int = None,
clarifai/client/search.py CHANGED
@@ -10,7 +10,8 @@ from schema import SchemaError
10
10
  from clarifai.client.base import BaseClient
11
11
  from clarifai.client.input import Inputs
12
12
  from clarifai.client.lister import Lister
13
- from clarifai.constants.search import DEFAULT_SEARCH_METRIC, DEFAULT_TOP_K
13
+ from clarifai.constants.search import (DEFAULT_SEARCH_ALGORITHM, DEFAULT_SEARCH_METRIC,
14
+ DEFAULT_TOP_K)
14
15
  from clarifai.errors import UserError
15
16
  from clarifai.schema.search import get_schema
16
17
 
@@ -20,11 +21,14 @@ class Search(Lister, BaseClient):
20
21
  def __init__(self,
21
22
  user_id: str,
22
23
  app_id: str,
23
- top_k: int = DEFAULT_TOP_K,
24
+ top_k: int = None,
24
25
  metric: str = DEFAULT_SEARCH_METRIC,
26
+ algorithm: str = DEFAULT_SEARCH_ALGORITHM,
27
+ pagination: bool = False,
25
28
  base_url: str = "https://api.clarifai.com",
26
29
  pat: str = None,
27
- token: str = None):
30
+ token: str = None,
31
+ root_certificates_path: str = None):
28
32
  """Initialize the Search object.
29
33
 
30
34
  Args:
@@ -32,27 +36,47 @@ class Search(Lister, BaseClient):
32
36
  app_id (str): App ID.
33
37
  top_k (int, optional): Top K results to retrieve. Defaults to 10.
34
38
  metric (str, optional): Similarity metric (either 'cosine' or 'euclidean'). Defaults to 'cosine'.
39
+ alogrithm (str, optional): Search algorithm (either 'nearest_neighbor' or 'brute_force'). Defaults to 'nearest_neighbor'.
40
+ pagination (bool, optional): Enable pagination. Defaults to False.
35
41
  base_url (str, optional): Base API url. Defaults to "https://api.clarifai.com".
36
42
  pat (str, optional): A personal access token for authentication. Can be set as env var CLARIFAI_PAT
37
43
  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
+ root_certificates_path (str): Path to the SSL root certificates file, used to establish secure gRPC connections.
38
45
 
39
46
  Raises:
40
47
  UserError: If the metric is not 'cosine' or 'euclidean'.
48
+ UserError: If the algorithm is not 'nearest_neighbor' or 'brute_force'.
41
49
  """
42
50
  if metric not in ["cosine", "euclidean"]:
43
51
  raise UserError("Metric should be either cosine or euclidean")
52
+ if algorithm not in ["nearest_neighbor", "brute_force"]:
53
+ raise UserError("Algorithm should be either nearest_neighbor or brute_force")
54
+ if metric == "cosine" and algorithm == "nearest_neighbor":
55
+ raise UserError("Cosine distance metric is not supported with nearest neighbor algorithm")
56
+ if top_k and pagination:
57
+ raise UserError(
58
+ "top_k and pagination cannot be used together. Please set pagination to False.")
59
+ if not top_k and not pagination:
60
+ top_k = DEFAULT_TOP_K
44
61
 
45
62
  self.user_id = user_id
46
63
  self.app_id = app_id
47
64
  self.metric_distance = dict(cosine="COSINE_DISTANCE", euclidean="EUCLIDEAN_DISTANCE")[metric]
65
+ self.algorithm = algorithm
48
66
  self.data_proto = resources_pb2.Data()
49
67
  self.top_k = top_k
50
-
68
+ self.pagination = pagination
51
69
  self.inputs = Inputs(
52
70
  user_id=self.user_id, app_id=self.app_id, pat=pat, token=token, base_url=base_url)
53
71
  self.rank_filter_schema = get_schema()
54
72
  BaseClient.__init__(
55
- self, user_id=self.user_id, app_id=self.app_id, base=base_url, pat=pat, token=token)
73
+ self,
74
+ user_id=self.user_id,
75
+ app_id=self.app_id,
76
+ base=base_url,
77
+ pat=pat,
78
+ token=token,
79
+ root_certificates_path=root_certificates_path)
56
80
  Lister.__init__(self, page_size=1000)
57
81
 
58
82
  def _get_annot_proto(self, **kwargs):
@@ -151,9 +175,8 @@ class Search(Lister, BaseClient):
151
175
  geo_point=resources_pb2.GeoPoint(longitude=longitude, latitude=latitude),
152
176
  geo_limit=resources_pb2.GeoLimit(type="withinKilometers", value=geo_limit))
153
177
 
154
- def list_all_pages_generator(
155
- self, endpoint: Callable[..., Any], proto_message: Any,
156
- request_data: Dict[str, Any]) -> Generator[Dict[str, Any], None, None]:
178
+ def _list_topk_generator(self, endpoint: Callable[..., Any], proto_message: Any,
179
+ request_data: Dict[str, Any]) -> Generator[Dict[str, Any], None, None]:
157
180
  """Lists all pages of a resource.
158
181
 
159
182
  Args:
@@ -191,12 +214,61 @@ class Search(Lister, BaseClient):
191
214
  total_hits += per_page
192
215
  yield response
193
216
 
194
- def query(self, ranks=[{}], filters=[{}]):
217
+ def _list_all_pages_generator(self,
218
+ endpoint: Callable,
219
+ proto_message: Any,
220
+ request_data: Dict[str, Any],
221
+ page_no: int = None,
222
+ per_page: int = None) -> Generator[Dict[str, Any], None, None]:
223
+ """Lists pages of a resource.
224
+
225
+ Args:
226
+ endpoint (Callable): The endpoint to call.
227
+ proto_message (Any): The proto message to use.
228
+ request_data (dict): The request data to use.
229
+ page_no (int): The page number to list.
230
+ per_page (int): The number of items per page.
231
+
232
+ Yields:
233
+ response_dict: The next item in the listing.
234
+ """
235
+ page = 1 if not page_no else page_no
236
+ if page_no and not per_page:
237
+ per_page = self.default_page_size
238
+ while True:
239
+ request_data['pagination'] = service_pb2.Pagination(page=page, per_page=per_page)
240
+ response = self._grpc_request(endpoint, proto_message(**request_data))
241
+ dict_response = MessageToDict(response, preserving_proto_field_name=True)
242
+ if response.status.code != status_code_pb2.SUCCESS:
243
+ if "page * perPage cannot exceed" in str(response.status.details):
244
+ msg = (f"Your pagination is set to {page_no*per_page}. "
245
+ f"The current pagination settings exceed the limit. Please reach out to "
246
+ f"support@clarifai.com to request an increase for your use case.\n"
247
+ f"req_id: {response.status.req_id}")
248
+ raise UserError(msg)
249
+ else:
250
+ raise Exception(f"Listing failed with response {response!r}")
251
+ if 'hits' not in list(dict_response.keys()):
252
+ break
253
+ yield response
254
+ if page_no is not None or per_page is not None:
255
+ break
256
+ page += 1
257
+
258
+ def query(
259
+ self,
260
+ ranks=[{}],
261
+ filters=[{}],
262
+ page_no: int = None,
263
+ per_page: int = None,
264
+ ):
195
265
  """Perform a query with rank and filters.
196
266
 
197
267
  Args:
198
268
  ranks (List[Dict], optional): List of rank parameters. Defaults to [{}].
199
269
  filters (List[Dict], optional): List of filter parameters. Defaults to [{}].
270
+ page_no (int): The page number to list.
271
+ per_page (int): The number of items per page.
200
272
 
201
273
  Returns:
202
274
  Generator[Dict[str, Any], None, None]: A generator of query results.
@@ -209,13 +281,16 @@ class Search(Lister, BaseClient):
209
281
 
210
282
  Vector search over inputs
211
283
  >>> from clarifai.client.search import Search
212
- >>> search = Search(user_id='user_id', app_id='app_id', top_k=1, metric='cosine')
213
- >>> res = search.query(ranks=[{'image_url': 'https://samples.clarifai.com/dog.tiff'}])
284
+ >>> search = Search(user_id='user_id', app_id='app_id' , metric='cosine', pagination=True)
285
+ >>> res = search.query(ranks=[{'image_url': 'https://samples.clarifai.com/dog.tiff'}],page_no=2, per_page=5)
214
286
 
215
287
  Note:
216
288
  For schema of rank and filter, please refer to [schema](https://github.com/Clarifai/clarifai-python/tree/master/clarifai/schema/search.py).
217
289
  For more detailed search examples, please refer to [examples](https://github.com/Clarifai/examples/tree/main/search).
218
290
  """
291
+ if not self.pagination and (per_page or page_no):
292
+ raise UserError("Pagination settings are only available when pagination is enabled."
293
+ "Please set Search(pagination=True) while initializing Search().")
219
294
  try:
220
295
  self.rank_filter_schema.validate(ranks)
221
296
  self.rank_filter_schema.validate(filters)
@@ -241,11 +316,15 @@ class Search(Lister, BaseClient):
241
316
  searches=[
242
317
  resources_pb2.Search(
243
318
  query=resources_pb2.Query(ranks=all_ranks, filters=all_filters),
319
+ algorithm=self.algorithm,
244
320
  metric=self.metric_distance)
245
321
  ])
246
-
247
- return self.list_all_pages_generator(self.STUB.PostInputsSearches,
248
- service_pb2.PostInputsSearchesRequest, request_data)
322
+ if self.pagination:
323
+ return self._list_all_pages_generator(self.STUB.PostInputsSearches,
324
+ service_pb2.PostInputsSearchesRequest, request_data,
325
+ page_no, per_page)
326
+ return self._list_topk_generator(self.STUB.PostInputsSearches,
327
+ service_pb2.PostInputsSearchesRequest, request_data)
249
328
 
250
329
  # Calls PostAnnotationsSearches for annotation ranks, filters
251
330
  filters_annot_proto = []
@@ -261,8 +340,12 @@ class Search(Lister, BaseClient):
261
340
  searches=[
262
341
  resources_pb2.Search(
263
342
  query=resources_pb2.Query(ranks=all_ranks, filters=all_filters),
343
+ algorithm=self.algorithm,
264
344
  metric=self.metric_distance)
265
345
  ])
266
-
267
- return self.list_all_pages_generator(self.STUB.PostAnnotationsSearches,
268
- service_pb2.PostAnnotationsSearchesRequest, request_data)
346
+ if self.pagination:
347
+ return self._list_all_pages_generator(self.STUB.PostAnnotationsSearches,
348
+ service_pb2.PostAnnotationsSearchesRequest,
349
+ request_data, page_no, per_page)
350
+ return self._list_topk_generator(self.STUB.PostAnnotationsSearches,
351
+ service_pb2.PostAnnotationsSearchesRequest, request_data)
clarifai/client/user.py CHANGED
@@ -7,7 +7,6 @@ from google.protobuf.json_format import MessageToDict
7
7
  from clarifai.client.app import App
8
8
  from clarifai.client.base import BaseClient
9
9
  from clarifai.client.lister import Lister
10
- from clarifai.client.runner import Runner
11
10
  from clarifai.errors import UserError
12
11
  from clarifai.utils.logging import get_logger
13
12
 
@@ -20,6 +19,7 @@ class User(Lister, BaseClient):
20
19
  base_url: str = "https://api.clarifai.com",
21
20
  pat: str = None,
22
21
  token: str = None,
22
+ root_certificates_path: str = None,
23
23
  **kwargs):
24
24
  """Initializes an User object.
25
25
 
@@ -28,12 +28,20 @@ class User(Lister, BaseClient):
28
28
  base_url (str): Base API url. Default "https://api.clarifai.com"
29
29
  pat (str): A personal access token for authentication. Can be set as env var CLARIFAI_PAT
30
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
31
+ root_certificates_path (str): Path to the SSL root certificates file, used to establish secure gRPC connections.
31
32
  **kwargs: Additional keyword arguments to be passed to the User.
32
33
  """
33
34
  self.kwargs = {**kwargs, 'id': user_id}
34
35
  self.user_info = resources_pb2.User(**self.kwargs)
35
36
  self.logger = get_logger(logger_level="INFO", name=__name__)
36
- BaseClient.__init__(self, user_id=self.id, app_id="", base=base_url, pat=pat, token=token)
37
+ BaseClient.__init__(
38
+ self,
39
+ user_id=self.id,
40
+ app_id="",
41
+ base=base_url,
42
+ pat=pat,
43
+ token=token,
44
+ root_certificates_path=root_certificates_path)
37
45
  Lister.__init__(self)
38
46
 
39
47
  def list_apps(self, filter_by: Dict[str, Any] = {}, page_no: int = None,
@@ -69,7 +77,7 @@ class User(Lister, BaseClient):
69
77
  **app_info) #(base_url=self.base, pat=self.pat, token=self.token, **app_info)
70
78
 
71
79
  def list_runners(self, filter_by: Dict[str, Any] = {}, page_no: int = None,
72
- per_page: int = None) -> Generator[Runner, None, None]:
80
+ per_page: int = None) -> Generator[dict, None, None]:
73
81
  """List all runners for the user
74
82
 
75
83
  Args:
@@ -78,7 +86,7 @@ class User(Lister, BaseClient):
78
86
  per_page (int): The number of items per page.
79
87
 
80
88
  Yields:
81
- Runner: Runner objects for the runners.
89
+ Dict: Dictionaries containing information about the runners.
82
90
 
83
91
  Example:
84
92
  >>> from clarifai.client.user import User
@@ -98,8 +106,7 @@ class User(Lister, BaseClient):
98
106
  page_no=page_no)
99
107
 
100
108
  for runner_info in all_runners_info:
101
- yield Runner.from_auth_helper(
102
- auth=self.auth_helper, check_runner_exists=False, **runner_info)
109
+ yield dict(auth=self.auth_helper, check_runner_exists=False, **runner_info)
103
110
 
104
111
  def create_app(self, app_id: str, base_workflow: str = 'Empty', **kwargs) -> App:
105
112
  """Creates an app for the user.
@@ -127,7 +134,7 @@ class User(Lister, BaseClient):
127
134
  self.logger.info("\nApp created\n%s", response.status)
128
135
  return App.from_auth_helper(auth=self.auth_helper, app_id=app_id)
129
136
 
130
- def create_runner(self, runner_id: str, labels: List[str], description: str) -> Runner:
137
+ def create_runner(self, runner_id: str, labels: List[str], description: str) -> dict:
131
138
  """Create a runner
132
139
 
133
140
  Args:
@@ -136,13 +143,14 @@ class User(Lister, BaseClient):
136
143
  description (str): Description of Runner
137
144
 
138
145
  Returns:
139
- Runner: A runner object for the specified Runner ID
146
+ Dict: A dictionary containing information about the specified Runner ID.
140
147
 
141
148
  Example:
142
149
  >>> from clarifai.client.user import User
143
150
  >>> client = User(user_id="user_id")
144
- >>> runner = client.create_runner(runner_id="runner_id", labels=["label to link runner"], description="laptop runner")
151
+ >>> runner_info = client.create_runner(runner_id="runner_id", labels=["label to link runner"], description="laptop runner")
145
152
  """
153
+
146
154
  if not isinstance(labels, List):
147
155
  raise UserError("Labels must be a List of strings")
148
156
 
@@ -155,7 +163,7 @@ class User(Lister, BaseClient):
155
163
  raise Exception(response.status)
156
164
  self.logger.info("\nRunner created\n%s", response.status)
157
165
 
158
- return Runner.from_auth_helper(
166
+ return dict(
159
167
  auth=self.auth_helper,
160
168
  runner_id=runner_id,
161
169
  user_id=self.id,
@@ -186,19 +194,19 @@ class User(Lister, BaseClient):
186
194
  kwargs['user_id'] = self.id
187
195
  return App.from_auth_helper(auth=self.auth_helper, app_id=app_id, **kwargs)
188
196
 
189
- def runner(self, runner_id: str) -> Runner:
197
+ def runner(self, runner_id: str) -> dict:
190
198
  """Returns a Runner object if exists.
191
199
 
192
200
  Args:
193
201
  runner_id (str): The runner ID to interact with
194
202
 
195
203
  Returns:
196
- Runner: A Runner object for the existing runner ID.
204
+ Dict: A dictionary containing information about the existing runner ID.
197
205
 
198
206
  Example:
199
207
  >>> from clarifai.client.user import User
200
208
  >>> client = User(user_id="user_id")
201
- >>> runner = client.runner(runner_id="runner_id")
209
+ >>> runner_info = client.runner(runner_id="runner_id")
202
210
  """
203
211
  request = service_pb2.GetRunnerRequest(user_app_id=self.user_app_id, runner_id=runner_id)
204
212
  response = self._grpc_request(self.STUB.GetRunner, request)
@@ -212,7 +220,7 @@ class User(Lister, BaseClient):
212
220
  kwargs = self.process_response_keys(dict_response[list(dict_response.keys())[1]],
213
221
  list(dict_response.keys())[1])
214
222
 
215
- return Runner.from_auth_helper(self.auth_helper, check_runner_exists=False, **kwargs)
223
+ return dict(self.auth_helper, check_runner_exists=False, **kwargs)
216
224
 
217
225
  def delete_app(self, app_id: str) -> None:
218
226
  """Deletes an app for the user.
@@ -28,6 +28,7 @@ class Workflow(Lister, BaseClient):
28
28
  base_url: str = "https://api.clarifai.com",
29
29
  pat: str = None,
30
30
  token: str = None,
31
+ root_certificates_path: str = None,
31
32
  **kwargs):
32
33
  """Initializes a Workflow object.
33
34
 
@@ -43,6 +44,7 @@ class Workflow(Lister, BaseClient):
43
44
  base_url (str): Base API url. Default "https://api.clarifai.com"
44
45
  pat (str): A personal access token for authentication. Can be set as env var CLARIFAI_PAT
45
46
  token (str): A session token for authentication. Accepts either a session token or a pat. Can be set as env var CLARIFAI_SESSION_TOKEN
47
+ root_certificates_path (str): Path to the SSL root certificates file, used to establish secure gRPC connections.
46
48
  **kwargs: Additional keyword arguments to be passed to the Workflow.
47
49
  """
48
50
  if url and workflow_id:
@@ -59,7 +61,13 @@ class Workflow(Lister, BaseClient):
59
61
  self.workflow_info = resources_pb2.Workflow(**self.kwargs)
60
62
  self.logger = get_logger(logger_level="INFO", name=__name__)
61
63
  BaseClient.__init__(
62
- self, user_id=self.user_id, app_id=self.app_id, base=base_url, pat=pat, token=token)
64
+ self,
65
+ user_id=self.user_id,
66
+ app_id=self.app_id,
67
+ base=base_url,
68
+ pat=pat,
69
+ token=token,
70
+ root_certificates_path=root_certificates_path)
63
71
  Lister.__init__(self)
64
72
 
65
73
  def predict(self, inputs: List[Input], workflow_state_id: str = None):
@@ -0,0 +1 @@
1
+ MAX_UPLOAD_BATCH_SIZE = 128
@@ -1,2 +1,3 @@
1
1
  DEFAULT_TOP_K = 10
2
- DEFAULT_SEARCH_METRIC = "cosine"
2
+ DEFAULT_SEARCH_METRIC = "euclidean"
3
+ DEFAULT_SEARCH_ALGORITHM = "nearest_neighbor"
@@ -141,6 +141,9 @@ Get your PAT from https://clarifai.com/settings/security and pass it here: <inse
141
141
  Upload
142
142
 
143
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
144
147
  $ clarifai upload model --url <url> --user-app <your_user_id>/<your_app_id> --id <your_model_id>
145
148
  ```
146
149
 
@@ -14,14 +14,11 @@
14
14
  import argparse
15
15
  import os
16
16
  import subprocess
17
- from typing import Union
18
17
 
19
- from clarifai.client.auth.helper import ClarifaiAuthHelper
20
- from clarifai.models.api import Models
21
- from clarifai.models.model_serving.model_config import (MODEL_TYPES, get_model_config,
22
- load_user_config)
18
+ from clarifai.models.model_serving.model_config import get_model_config, load_user_config
23
19
  from clarifai.models.model_serving.model_config.inference_parameter import InferParamManager
24
20
 
21
+ from ..constants import BUILT_MODEL_EXT
25
22
  from ..utils import login
26
23
  from .base import BaseClarifaiCli
27
24
 
@@ -51,7 +48,9 @@ class UploadModelSubCli(BaseClarifaiCli):
51
48
  "Path to working dir to get clarifai_config.yaml or path to yaml. Default is current directory",
52
49
  default=".")
53
50
  upload_parser.add_argument(
54
- "--url", type=str, required=True, help="Direct download url of zip file")
51
+ "--url", type=str, required=False, help="Direct download url of zip file", default=None)
52
+ upload_parser.add_argument(
53
+ "--file", type=str, required=False, help="Local built file", default=None)
55
54
  upload_parser.add_argument("--id", type=str, required=False, help="Model ID")
56
55
  upload_parser.add_argument(
57
56
  "--user-app",
@@ -62,7 +61,10 @@ class UploadModelSubCli(BaseClarifaiCli):
62
61
  "--no-test",
63
62
  action="store_true",
64
63
  help="Trigger this flag to skip testing before uploading")
65
-
64
+ upload_parser.add_argument(
65
+ "--no-resume",
66
+ action="store_true",
67
+ help="Trigger this flag to not resume uploading local file")
66
68
  upload_parser.add_argument(
67
69
  "--update-version",
68
70
  action="store_true",
@@ -73,10 +75,13 @@ class UploadModelSubCli(BaseClarifaiCli):
73
75
 
74
76
  def __init__(self, args: argparse.Namespace) -> None:
75
77
  self.no_test = args.no_test
78
+ self.no_resume = args.no_resume
76
79
 
77
80
  working_dir_or_config = args.path
78
81
  # if input a config file, then not running test
79
82
  if working_dir_or_config.endswith(".yaml"):
83
+ # to folder
84
+ working_dir_or_config = os.path.split(working_dir_or_config)[0]
80
85
  config_yaml_path = working_dir_or_config
81
86
  self.test_path = None
82
87
  self.no_test = True
@@ -89,12 +94,27 @@ class UploadModelSubCli(BaseClarifaiCli):
89
94
  f"`{config_yaml_path}` does not exist")
90
95
  self.config = load_user_config(cfg_path=config_yaml_path)
91
96
 
97
+ self.file = args.file
98
+ self.url = args.url
99
+ if self.file:
100
+ assert self.url, ValueError("Provide either file or url, but got both.")
101
+ assert os.path.exists(self.file), FileNotFoundError
102
+ elif self.url:
103
+ assert self.url.startswith("http") or self.url.startswith(
104
+ "s3"), f"Invalid url supported http or s3 url. Got {self.url}"
105
+ self.file = None
106
+ else:
107
+ for _fname in os.listdir(working_dir_or_config):
108
+ if _fname.endswith(BUILT_MODEL_EXT):
109
+ self.file = os.path.join(working_dir_or_config, _fname)
110
+ break
111
+ assert self.file, ValueError(
112
+ f"Not using url/file but also not found built file with extension {BUILT_MODEL_EXT}")
113
+
92
114
  self.user_id, self.app_id = "", ""
93
115
  user_app = args.user_app
94
116
  self.url: str = args.url
95
117
  self.update_version = args.update_version
96
- assert self.url.startswith("http") or self.url.startswith(
97
- "s3"), f"Invalid url supported http or s3 url. Got {self.url}"
98
118
 
99
119
  clarifai_cfg = self.config.clarifai_model
100
120
  self.url: str = args.url
@@ -111,17 +131,10 @@ class UploadModelSubCli(BaseClarifaiCli):
111
131
  ) == 2, f"id must be combination of user_id and app_id separated by `/`, e.g. <user_id>/<app_id>. Got {args.id}"
112
132
  self.user_id, self.app_id = user_app
113
133
 
114
- if self.user_id:
115
- os.environ["CLARIFAI_USER_ID"] = self.user_id
116
- if self.app_id:
117
- os.environ["CLARIFAI_APP_ID"] = self.app_id
118
-
119
- _user_id = os.environ.get("CLARIFAI_USER_ID", None)
120
- _app_id = os.environ.get("CLARIFAI_APP_ID", None)
121
- assert _user_id or _app_id, f"Missing user-id or app-id, got user-id {_user_id} and app-id {_app_id}"
122
134
  login()
123
135
 
124
136
  def run(self):
137
+ from clarifai.client import App, Model
125
138
 
126
139
  # Run test before uploading
127
140
  if not self.no_test:
@@ -129,54 +142,38 @@ class UploadModelSubCli(BaseClarifaiCli):
129
142
  result = subprocess.run(f"pytest -s --log-level=INFO {self.test_path}", shell=True)
130
143
  assert result.returncode == 0, "Test has failed. Please make sure no error exists in your code."
131
144
 
132
- deploy(
133
- model_url=self.url,
134
- model_id=self.id,
135
- desc=self.desc,
136
- model_type=self.type,
137
- update_version=self.update_version,
138
- inference_parameters=self.infer_param)
139
-
140
-
141
- def deploy(model_url,
142
- model_id: str = None,
143
- model_type: str = None,
144
- desc: str = "",
145
- update_version: bool = False,
146
- inference_parameters: Union[dict, str] = None):
147
- # init Auth from env vars
148
- auth = ClarifaiAuthHelper.from_env()
149
- # init api
150
- model_api = Models(auth)
151
- # key map
152
- assert model_type in MODEL_TYPES, f"model_type should be one of {MODEL_TYPES}"
153
- clarifai_key_map = get_model_config(model_type=model_type).clarifai_model.field_maps
154
- # inference parameters
155
- if isinstance(inference_parameters, str) and os.path.isfile(inference_parameters):
156
- inference_parameters = InferParamManager(json_path=inference_parameters).get_list_params()
157
- # if updating new version of existing model
158
- if update_version:
159
- resp = model_api.post_model_version(
160
- model_id=model_id,
161
- model_zip_url=model_url,
162
- input=clarifai_key_map.input_fields_map,
163
- outputs=clarifai_key_map.output_fields_map,
164
- param_specs=inference_parameters)
165
- # creating new model
166
- else:
167
- # post model
168
- resp = model_api.upload_model(
169
- model_id=model_id,
170
- model_zip_url=model_url,
171
- model_type=model_type,
172
- input=clarifai_key_map.input_fields_map,
173
- outputs=clarifai_key_map.output_fields_map,
174
- description=desc,
175
- param_specs=inference_parameters)
176
- # response
177
- if resp["status"]["code"] != "SUCCESS":
178
- raise Exception("Post models failed, details: {}, {}".format(resp["status"]["description"],
179
- resp["status"]["details"]))
180
- else:
181
- print("Success!")
182
- print(f'Model version: {resp["model"]["model_version"]["id"]}')
145
+ clarifai_key_map = get_model_config(model_type=self.type).clarifai_model.field_maps
146
+ # inference parameters
147
+ inference_parameters = None
148
+ if isinstance(self.infer_param, str) and os.path.isfile(self.infer_param):
149
+ inference_parameters = InferParamManager(json_path=self.infer_param).get_list_params()
150
+ inputs = clarifai_key_map.input_fields_map
151
+ outputs = clarifai_key_map.output_fields_map
152
+
153
+ # if updating new version of existing model
154
+ def update_version():
155
+ model = Model(model_id=self.id, app_id=self.app_id)
156
+ if self.url:
157
+ model.create_version_by_url(
158
+ url=self.url,
159
+ input_field_maps=inputs,
160
+ output_field_maps=outputs,
161
+ inference_parameter_configs=inference_parameters,
162
+ description=self.desc)
163
+ elif self.file:
164
+ model.create_version_by_file(
165
+ file_path=self.file,
166
+ input_field_maps=inputs,
167
+ output_field_maps=outputs,
168
+ inference_parameter_configs=inference_parameters,
169
+ no_resume=self.no_resume,
170
+ description=self.desc)
171
+ else:
172
+ raise ValueError
173
+
174
+ if self.update_version:
175
+ update_version()
176
+ else:
177
+ # creating new model
178
+ _ = App(app_id=self.app_id).create_model(self.id, model_type_id=self.type)
179
+ update_version()
@@ -127,7 +127,15 @@ optional arguments:
127
127
 
128
128
  5. Upload
129
129
 
130
- This step will run `test.py` in provided working dir as default before building
130
+ This step will execute test.py in the specified working directory by default before proceeding with the build. You can upload your built file directly from the working directory to the platform or upload it to cloud storage and provide the direct URL during the upload process.
131
+
132
+ Use the following command to upload your built file directly to the platform. It will upload the `*.clarifai` file. *Note*: Only support file size from 5MiB to 5GiB
133
+
134
+ ```bash
135
+ $ clarifai upload model <your_working_dir>
136
+ ```
137
+
138
+ or upload with direct download url
131
139
 
132
140
  ```bash
133
141
  $ clarifai upload model <your_working_dir> --url <your url>
@@ -141,10 +149,13 @@ positional arguments:
141
149
  path Path to working dir to get clarifai_config.yaml or path to yaml. Default is current directory
142
150
 
143
151
  optional arguments:
144
- --url Direct download url of zip file
145
- --id Model ID
146
- --user-app User ID and App ID separated by '/', e.g., <user_id>/<app_id>
147
- --update-version Update exist model with new version
148
- --no-test Trigger this flag to skip testing before uploading
152
+ -h, --help show this help message and exit
153
+ --url URL Direct download url of zip file
154
+ --file FILE Local built file
155
+ --id ID Model ID
156
+ --user-app USER_APP User ID and App ID separated by '/', e.g., <user_id>/<app_id>
157
+ --no-test Trigger this flag to skip testing before uploading
158
+ --no-resume Trigger this flag to not resume uploading local file
159
+ --update-version Update exist model with new version
149
160
 
150
161
  ```
clarifai/rag/rag.py CHANGED
@@ -110,7 +110,7 @@ class RAG:
110
110
  prompter_model_params = {"params": params}
111
111
 
112
112
  ## Create rag-prompter model and version
113
- model_id = f"prompter-{workflow_id}" if workflow_id is not None else f"rag-prompter-{now_ts}"
113
+ model_id = f"prompter-{workflow_id}-{now_ts}" if workflow_id is not None else f"rag-prompter-{now_ts}"
114
114
  prompter_model = app.create_model(model_id=model_id, model_type_id="rag-prompter")
115
115
  prompter_model = prompter_model.create_version(output_info=prompter_model_params)
116
116
 
clarifai/rag/utils.py CHANGED
@@ -67,7 +67,7 @@ def load_documents(file_path: str = None, folder_path: str = None, url: str = No
67
67
  #document loaders for folderpath
68
68
  if folder_path:
69
69
  documents = SimpleDirectoryReader(
70
- input_dir=Path(folder_path), required_exts=[".pdf", ".docx"]).load_data()
70
+ input_dir=Path(folder_path), required_exts=[".pdf", ".docx", ".txt"]).load_data()
71
71
 
72
72
  #document loaders for url
73
73
  if url: