clarifai 11.6.5__py3-none-any.whl → 11.6.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
clarifai/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "11.6.5"
1
+ __version__ = "11.6.7"
clarifai/cli/README.md CHANGED
@@ -121,6 +121,57 @@ Delete existing Compute Clusters:
121
121
  $ clarifai computecluster delete --compute_cluster_id <compute-cluster-id>
122
122
  ```
123
123
 
124
+ ## Pipelines
125
+
126
+ ### List Pipelines
127
+
128
+ List all pipelines for the user across all apps:
129
+
130
+ ```bash
131
+ $ clarifai pipeline list
132
+ ```
133
+
134
+ List pipelines within a specific app:
135
+
136
+ ```bash
137
+ $ clarifai pipeline list --app_id <app-id>
138
+ ```
139
+
140
+ List with pagination:
141
+
142
+ ```bash
143
+ $ clarifai pipeline list --page_no 1 --per_page 10
144
+ ```
145
+
146
+ ### List Pipeline Steps
147
+
148
+ List all pipeline steps for the user across all apps:
149
+
150
+ ```bash
151
+ $ clarifai pipelinestep list
152
+ ```
153
+
154
+ List pipeline steps within a specific app:
155
+
156
+ ```bash
157
+ $ clarifai pipelinestep list --app_id <app-id>
158
+ ```
159
+
160
+ List pipeline steps for a specific pipeline:
161
+
162
+ ```bash
163
+ $ clarifai pipelinestep list --app_id <app-id> --pipeline_id <pipeline-id>
164
+ ```
165
+
166
+ ### Aliases
167
+
168
+ Both commands support the `ls` alias for convenience:
169
+
170
+ ```bash
171
+ $ clarifai pipeline ls
172
+ $ clarifai pipelinestep ls
173
+ ```
174
+
124
175
  ## Learn More
125
176
 
126
177
  * [Example Configs](https://github.com/Clarifai/examples/tree/main/ComputeOrchestration/configs)
clarifai/cli/base.py CHANGED
@@ -1,3 +1,4 @@
1
+ import getpass
1
2
  import json
2
3
  import os
3
4
  import sys
@@ -71,33 +72,44 @@ def login(ctx, api_url, user_id):
71
72
  """Login command to set PAT and other configurations."""
72
73
  from clarifai.utils.cli import validate_context_auth
73
74
 
74
- name = input('context name (default: "default"): ')
75
- user_id = user_id if user_id is not None else input('user id: ')
76
- pat = input_or_default(
77
- 'personal access token value (default: "ENVVAR" to get out of env var rather than config): ',
78
- 'ENVVAR',
75
+ # Input user_id if not supplied
76
+ if not user_id:
77
+ user_id = click.prompt('Enter your Clarifai user ID', type=str)
78
+
79
+ click.echo('> To authenticate, you\'ll need a Personal Access Token (PAT).')
80
+ click.echo(
81
+ f'> You can create one from your account settings: https://clarifai.com/{user_id}/settings/security\n'
79
82
  )
80
83
 
81
- # Validate the Context Credentials
84
+ # Securely input PAT
85
+ pat = getpass.getpass('Enter your Personal Access Token: ')
86
+
87
+ # Progress indicator
88
+ click.echo('\n> Verifying token...')
82
89
  validate_context_auth(pat, user_id, api_url)
83
90
 
91
+ # Context naming
92
+ default_context_name = 'default'
93
+ click.echo('\n> Let\'s save these credentials to a new context.')
94
+ click.echo('> You can have multiple contexts to easily switch between accounts or projects.\n')
95
+ context_name = click.prompt("Enter a name for this context", default=default_context_name)
96
+
97
+ # Save context
84
98
  context = Context(
85
- name,
99
+ context_name,
86
100
  CLARIFAI_API_BASE=api_url,
87
101
  CLARIFAI_USER_ID=user_id,
88
102
  CLARIFAI_PAT=pat,
89
103
  )
90
104
 
91
- if context.name == '':
92
- context.name = 'default'
93
-
94
- ctx.obj.contexts[context.name] = context
95
- ctx.obj.current_context = context.name
96
-
105
+ ctx.obj.contexts[context_name] = context
106
+ ctx.obj.current_context = context_name
97
107
  ctx.obj.to_yaml()
98
- logger.info(
99
- f"Login successful and Configuration saved successfully for context '{context.name}'"
100
- )
108
+ click.secho('✅ Success! You are now logged in.', fg='green')
109
+ click.echo(f'Credentials saved to the \'{context_name}\' context.\n')
110
+ click.echo('💡 To switch contexts later, use `clarifai config use-context <name>`.')
111
+
112
+ logger.info(f"Login successful for user '{user_id}' in context '{context_name}'")
101
113
 
102
114
 
103
115
  def pat_display(pat):
@@ -110,7 +122,7 @@ def input_or_default(prompt, default):
110
122
 
111
123
 
112
124
  # Context management commands under config group
113
- @config.command(aliases=['get-contexts', 'list-contexts'])
125
+ @config.command(aliases=['get-contexts', 'list-contexts', 'ls'])
114
126
  @click.option(
115
127
  '-o', '--output-format', default='wide', type=click.Choice(['wide', 'name', 'json', 'yaml'])
116
128
  )
@@ -149,7 +161,7 @@ def get_contexts(ctx, output_format):
149
161
  print(yaml.safe_dump(dicts))
150
162
 
151
163
 
152
- @config.command(aliases=['use-context'])
164
+ @config.command(aliases=['use-context', 'use'])
153
165
  @click.argument('name', type=str)
154
166
  @click.pass_context
155
167
  def use_context(ctx, name):
@@ -161,7 +173,7 @@ def use_context(ctx, name):
161
173
  print(f'Set {name} as the current context')
162
174
 
163
175
 
164
- @config.command(aliases=['current-context'])
176
+ @config.command(aliases=['current-context', 'current'])
165
177
  @click.option('-o', '--output-format', default='name', type=click.Choice(['name', 'json', 'yaml']))
166
178
  @click.pass_context
167
179
  def current_context(ctx, output_format):
@@ -174,7 +186,7 @@ def current_context(ctx, output_format):
174
186
  print(yaml.safe_dump(ctx.obj.contexts[ctx.obj.current_context].to_serializable_dict()))
175
187
 
176
188
 
177
- @config.command(aliases=['create-context', 'set-context'])
189
+ @config.command(aliases=['create-context', 'create'])
178
190
  @click.argument('name')
179
191
  @click.option('--user-id', required=False, help='User ID')
180
192
  @click.option('--base-url', required=False, help='Base URL')
@@ -221,7 +233,7 @@ def edit(
221
233
  os.system(f'{os.environ.get("EDITOR", "vi")} {ctx.obj.filename}')
222
234
 
223
235
 
224
- @config.command(aliases=['delete-context'])
236
+ @config.command(aliases=['delete-context', 'delete'])
225
237
  @click.argument('name')
226
238
  @click.pass_context
227
239
  def delete_context(ctx, name):
clarifai/cli/model.py CHANGED
@@ -9,6 +9,7 @@ from clarifai.utils.cli import (
9
9
  check_ollama_installed,
10
10
  check_requirements_installed,
11
11
  customize_ollama_model,
12
+ parse_requirements,
12
13
  validate_context,
13
14
  )
14
15
  from clarifai.utils.constants import (
@@ -83,7 +84,14 @@ def model():
83
84
  required=False,
84
85
  )
85
86
  def init(
86
- model_path, model_type_id, github_pat, github_url, toolkit, model_name, port, context_length
87
+ model_path,
88
+ model_type_id,
89
+ github_pat,
90
+ github_url,
91
+ toolkit,
92
+ model_name,
93
+ port,
94
+ context_length,
87
95
  ):
88
96
  """Initialize a new model directory structure.
89
97
 
@@ -99,6 +107,13 @@ def init(
99
107
  branch to clone from.
100
108
 
101
109
  MODEL_PATH: Path where to create the model directory structure. If not specified, the current directory is used by default.
110
+ MODEL_TYPE_ID: Type of model to create. If not specified, defaults to "text-to-text" for text models.
111
+ GITHUB_PAT: GitHub Personal Access Token for authentication when cloning private repositories.
112
+ GITHUB_URL: GitHub repository URL or "repo" format to clone a repository from. If provided, the entire repository contents will be copied to the target directory instead of using default templates.
113
+ TOOLKIT: Toolkit to use for model initialization. Currently supports "ollama".
114
+ MODEL_NAME: Model name to configure when using --toolkit. For ollama toolkit, this sets the Ollama model to use (e.g., "llama3.1", "mistral", etc.).
115
+ PORT: Port to run the Ollama server on. Defaults to 23333.
116
+ CONTEXT_LENGTH: Context length for the Ollama model. Defaults to 8192.
102
117
  """
103
118
  # Resolve the absolute path
104
119
  model_path = os.path.abspath(model_path)
@@ -509,8 +524,13 @@ def run_locally(model_path, port, mode, keep_env, keep_image, skip_dockerfile=Fa
509
524
  show_default=True,
510
525
  help="The number of threads to use. On community plan, the compute time allocation is drained at a rate proportional to the number of threads.",
511
526
  ) # pylint: disable=range-builtin-not-iterating
527
+ @click.option(
528
+ '--verbose',
529
+ is_flag=True,
530
+ help='Show detailed logs including Ollama server output. By default, Ollama logs are suppressed.',
531
+ )
512
532
  @click.pass_context
513
- def local_runner(ctx, model_path, pool_size):
533
+ def local_runner(ctx, model_path, pool_size, verbose):
514
534
  """Run the model as a local runner to help debug your model connected to the API or to
515
535
  leverage local compute resources manually. This relies on many variables being present in the env
516
536
  of the currently selected context. If they are not present then default values will be used to
@@ -552,7 +572,23 @@ def local_runner(ctx, model_path, pool_size):
552
572
  from clarifai.runners.server import serve
553
573
 
554
574
  validate_context(ctx)
555
- logger.info("Checking setup for local runner...")
575
+ builder = ModelBuilder(model_path, download_validation_only=True)
576
+ logger.info("> Checking local runner requirements...")
577
+ if not check_requirements_installed(model_path):
578
+ logger.error(f"Requirements not installed for model at {model_path}.")
579
+ raise click.Abort()
580
+
581
+ # Post check while running `clarifai model local-runner` we check if the toolkit is ollama
582
+ dependencies = parse_requirements(model_path)
583
+ if "ollama" in dependencies or builder.config.get('toolkit', {}).get('provider') == 'ollama':
584
+ logger.info("Verifying Ollama installation...")
585
+ if not check_ollama_installed():
586
+ logger.error(
587
+ "Ollama application is not installed. Please install it from `https://ollama.com/` to use the Ollama toolkit."
588
+ )
589
+ raise click.Abort()
590
+
591
+ logger.info("> Verifying local runner setup...")
556
592
  logger.info(f"Current context: {ctx.obj.current.name}")
557
593
  user_id = ctx.obj.current.user_id
558
594
  logger.info(f"Current user_id: {user_id}")
@@ -693,8 +729,12 @@ def local_runner(ctx, model_path, pool_size):
693
729
  if len(model_versions) == 0:
694
730
  logger.warning("No model versions found. Creating a new version for local runner.")
695
731
  version = model.create_version(pretrained_model_config={"local_dev": True}).model_version
732
+ ctx.obj.current.CLARIFAI_MODEL_VERSION_ID = version.id
733
+ ctx.obj.to_yaml()
696
734
  else:
697
735
  version = model_versions[0].model_version
736
+ ctx.obj.current.CLARIFAI_MODEL_VERSION_ID = version.id
737
+ ctx.obj.to_yaml() # save to yaml file.
698
738
 
699
739
  logger.info(f"Current model version {version.id}")
700
740
 
@@ -796,10 +836,6 @@ def local_runner(ctx, model_path, pool_size):
796
836
 
797
837
  logger.info(f"Current deployment_id: {deployment_id}")
798
838
 
799
- logger.info(
800
- f"Full url for the model:\n{ctx.obj.current.ui}/users/{user_id}/apps/{app_id}/models/{model.id}/versions/{version.id}"
801
- )
802
-
803
839
  # Now that we have all the context in ctx.obj, we need to update the config.yaml in
804
840
  # the model_path directory with the model object containing user_id, app_id, model_id, version_id
805
841
  config_file = os.path.join(model_path, 'config.yaml')
@@ -837,6 +873,16 @@ def local_runner(ctx, model_path, pool_size):
837
873
  )
838
874
  raise click.Abort()
839
875
 
876
+ try:
877
+ logger.info("Customizing Ollama model with provided parameters...")
878
+ customize_ollama_model(
879
+ model_path=model_path,
880
+ verbose=True if verbose else False,
881
+ )
882
+ except Exception as e:
883
+ logger.error(f"Failed to customize Ollama model: {e}")
884
+ raise click.Abort()
885
+
840
886
  # don't mock for local runner since you need the dependencies to run the code anyways.
841
887
  method_signatures = builder.get_method_signatures(mocking=False)
842
888
 
@@ -861,7 +907,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
861
907
  f"Playground: To chat with your model, visit:\n{ctx.obj.current.ui}/playground?model={model.id}__{version.id}&user_id={user_id}&app_id={app_id}"
862
908
  )
863
909
 
864
- logger.info("Now starting the local runner...")
910
+ logger.info(" Starting local runner...")
865
911
 
866
912
  # This reads the config.yaml from the model_path so we alter it above first.
867
913
  serve(
@@ -874,6 +920,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
874
920
  runner_id=runner_id,
875
921
  base_url=ctx.obj.current.api_base,
876
922
  pat=ctx.obj.current.pat,
923
+ context=ctx.obj.current,
877
924
  )
878
925
 
879
926
 
clarifai/cli/pipeline.py CHANGED
@@ -4,15 +4,24 @@ import shutil
4
4
  import click
5
5
 
6
6
  from clarifai.cli.base import cli
7
+ from clarifai.client.app import App
8
+ from clarifai.client.user import User
9
+ from clarifai.utils.cli import (
10
+ AliasedGroup,
11
+ convert_timestamp_to_string,
12
+ display_co_resources,
13
+ validate_context,
14
+ )
7
15
  from clarifai.utils.logging import logger
8
16
 
9
17
 
10
18
  @cli.group(
11
19
  ['pipeline', 'pl'],
20
+ cls=AliasedGroup,
12
21
  context_settings={'max_content_width': shutil.get_terminal_size().columns - 10},
13
22
  )
14
23
  def pipeline():
15
- """Manage pipelines: upload, init, etc"""
24
+ """Manage pipelines: upload, init, list, etc"""
16
25
 
17
26
 
18
27
  @pipeline.command()
@@ -113,6 +122,19 @@ def run(
113
122
  monitor_interval = config_data.get('monitor_interval', monitor_interval)
114
123
  log_file = config_data.get('log_file', log_file)
115
124
  monitor = config_data.get('monitor', monitor)
125
+ elif ctx.obj.current:
126
+ if not user_id:
127
+ user_id = ctx.obj.current.get('user_id', '')
128
+ if not app_id:
129
+ app_id = ctx.obj.current.get('app_id', '')
130
+ if not pipeline_id:
131
+ pipeline_id = ctx.obj.current.get('pipeline_id', '')
132
+ if not pipeline_version_id:
133
+ pipeline_version_id = ctx.obj.current.get('pipeline_version_id', '')
134
+ if not nodepool_id:
135
+ nodepool_id = ctx.obj.current.get('nodepool_id', '')
136
+ if not compute_cluster_id:
137
+ compute_cluster_id = ctx.obj.current.get('compute_cluster_id', '')
116
138
 
117
139
  # compute_cluster_id and nodepool_id are mandatory regardless of whether pipeline_url is provided
118
140
  if not compute_cluster_id or not nodepool_id:
@@ -275,3 +297,50 @@ def init(pipeline_path):
275
297
  )
276
298
  logger.info("4. Add dependencies to requirements.txt files as needed")
277
299
  logger.info("5. Run 'clarifai pipeline upload config.yaml' to upload your pipeline")
300
+
301
+
302
+ @pipeline.command(['ls'])
303
+ @click.option('--page_no', required=False, help='Page number to list.', default=1)
304
+ @click.option('--per_page', required=False, help='Number of items per page.', default=16)
305
+ @click.option(
306
+ '--app_id',
307
+ required=False,
308
+ help='App ID to list pipelines from. If not provided, lists across all apps.',
309
+ )
310
+ @click.pass_context
311
+ def list(ctx, page_no, per_page, app_id):
312
+ """List all pipelines for the user."""
313
+ validate_context(ctx)
314
+
315
+ if app_id:
316
+ app = App(
317
+ app_id=app_id,
318
+ user_id=ctx.obj.current.user_id,
319
+ pat=ctx.obj.current.pat,
320
+ base_url=ctx.obj.current.api_base,
321
+ )
322
+ response = app.list_pipelines(page_no=page_no, per_page=per_page)
323
+ else:
324
+ user = User(
325
+ user_id=ctx.obj.current.user_id,
326
+ pat=ctx.obj.current.pat,
327
+ base_url=ctx.obj.current.api_base,
328
+ )
329
+ response = user.list_pipelines(page_no=page_no, per_page=per_page)
330
+
331
+ display_co_resources(
332
+ response,
333
+ custom_columns={
334
+ 'ID': lambda p: getattr(p, 'pipeline_id', ''),
335
+ 'USER_ID': lambda p: getattr(p, 'user_id', ''),
336
+ 'APP_ID': lambda p: getattr(p, 'app_id', ''),
337
+ 'VERSION_ID': lambda p: getattr(p, 'pipeline_version_id', ''),
338
+ 'DESCRIPTION': lambda p: getattr(p, 'description', ''),
339
+ 'CREATED_AT': lambda ps: convert_timestamp_to_string(getattr(ps, 'created_at', '')),
340
+ 'MODIFIED_AT': lambda ps: convert_timestamp_to_string(getattr(ps, 'modified_at', '')),
341
+ },
342
+ sort_by_columns=[
343
+ ('CREATED_AT', 'desc'),
344
+ ('ID', 'asc'),
345
+ ],
346
+ )
@@ -4,15 +4,24 @@ import shutil
4
4
  import click
5
5
 
6
6
  from clarifai.cli.base import cli
7
+ from clarifai.client.app import App
8
+ from clarifai.client.user import User
9
+ from clarifai.utils.cli import (
10
+ AliasedGroup,
11
+ convert_timestamp_to_string,
12
+ display_co_resources,
13
+ validate_context,
14
+ )
7
15
  from clarifai.utils.logging import logger
8
16
 
9
17
 
10
18
  @cli.group(
11
19
  ['pipelinestep', 'ps'],
20
+ cls=AliasedGroup,
12
21
  context_settings={'max_content_width': shutil.get_terminal_size().columns - 10},
13
22
  )
14
23
  def pipeline_step():
15
- """Manage pipeline steps: upload, test, etc"""
24
+ """Manage pipeline steps: upload, test, list, etc"""
16
25
 
17
26
 
18
27
  @pipeline_step.command()
@@ -102,3 +111,60 @@ def init(pipeline_step_path):
102
111
  logger.info("2. Update the pipeline step configuration in config.yaml")
103
112
  logger.info("3. Add your pipeline step dependencies to requirements.txt")
104
113
  logger.info("4. Implement your pipeline step logic in 1/pipeline_step.py")
114
+
115
+
116
+ @pipeline_step.command(['ls'])
117
+ @click.option('--page_no', required=False, help='Page number to list.', default=1)
118
+ @click.option('--per_page', required=False, help='Number of items per page.', default=16)
119
+ @click.option(
120
+ '--app_id',
121
+ required=False,
122
+ help='App ID to list pipeline steps from. If not provided, lists across all apps.',
123
+ )
124
+ @click.option(
125
+ '--pipeline_id',
126
+ required=False,
127
+ help='Pipeline ID to list pipeline steps from. Must be used with --app_id.',
128
+ )
129
+ @click.pass_context
130
+ def list(ctx, page_no, per_page, app_id, pipeline_id):
131
+ """List all pipeline steps for the user."""
132
+ validate_context(ctx)
133
+
134
+ if pipeline_id and not app_id:
135
+ raise click.UsageError("--pipeline_id must be used together with --app_id")
136
+
137
+ if app_id:
138
+ app = App(
139
+ app_id=app_id,
140
+ user_id=ctx.obj.current.user_id,
141
+ pat=ctx.obj.current.pat,
142
+ base_url=ctx.obj.current.api_base,
143
+ )
144
+ response = app.list_pipeline_steps(
145
+ pipeline_id=pipeline_id, page_no=page_no, per_page=per_page
146
+ )
147
+ else:
148
+ user = User(
149
+ user_id=ctx.obj.current.user_id,
150
+ pat=ctx.obj.current.pat,
151
+ base_url=ctx.obj.current.api_base,
152
+ )
153
+ response = user.list_pipeline_steps(page_no=page_no, per_page=per_page)
154
+
155
+ display_co_resources(
156
+ response,
157
+ custom_columns={
158
+ 'PIPELINE_STEP_ID': lambda ps: getattr(ps, 'pipeline_step_id', ''),
159
+ 'USER_ID': lambda ps: getattr(ps, 'user_id', ''),
160
+ 'APP_ID': lambda ps: getattr(ps, 'app_id', ''),
161
+ 'VERSION_ID': lambda ps: getattr(ps, 'pipeline_step_version_id', ''),
162
+ 'DESCRIPTION': lambda ps: getattr(ps, 'description', ''),
163
+ 'CREATED_AT': lambda ps: convert_timestamp_to_string(getattr(ps, 'created_at', '')),
164
+ 'MODIFIED_AT': lambda ps: convert_timestamp_to_string(getattr(ps, 'modified_at', '')),
165
+ },
166
+ sort_by_columns=[
167
+ ('CREATED_AT', 'desc'),
168
+ ('PIPELINE_STEP_ID', 'asc'),
169
+ ],
170
+ )
@@ -35,7 +35,7 @@ def get_pipeline_step_template():
35
35
  return '''import argparse
36
36
 
37
37
  import clarifai
38
-
38
+ from clarifai.utils.logging import logger
39
39
 
40
40
  def main():
41
41
  parser = argparse.ArgumentParser(description='Concatenate two strings.')
@@ -44,9 +44,9 @@ def main():
44
44
 
45
45
  args = parser.parse_args()
46
46
 
47
- print(clarifai.__version__)
47
+ logger.info(clarifai.__version__)
48
48
 
49
- print(f"Concatenation Output: {args.param_a + args.param_b}")
49
+ logger.info(f"Concatenation Output: {args.param_a + args.param_b}")
50
50
 
51
51
 
52
52
  if __name__ == "__main__":
@@ -25,12 +25,12 @@ def get_pipeline_config_template():
25
25
  steps:
26
26
  - - name: step-a
27
27
  templateRef:
28
- name: users/your_user_id/apps/your_app_id/pipeline-steps/stepA # TODO: please fill in
29
- template: users/your_user_id/apps/your_app_id/pipeline-steps/stepA # TODO: please fill in
28
+ name: users/your_user_id/apps/your_app_id/pipeline_steps/stepA # TODO: please fill in
29
+ template: users/your_user_id/apps/your_app_id/pipeline_steps/stepA # TODO: please fill in
30
30
  - - name: step-b
31
31
  templateRef:
32
- name: users/your_user_id/apps/your_app_id/pipeline-steps/stepB # TODO: please fill in
33
- template: users/your_user_id/apps/your_app_id/pipeline-steps/stepB # TODO: please fill in
32
+ name: users/your_user_id/apps/your_app_id/pipeline_steps/stepB # TODO: please fill in
33
+ template: users/your_user_id/apps/your_app_id/pipeline_steps/stepB # TODO: please fill in
34
34
  """
35
35
 
36
36
 
@@ -60,7 +60,7 @@ def get_pipeline_step_template(step_id: str):
60
60
  return f'''import argparse
61
61
 
62
62
  import clarifai
63
-
63
+ from clarifai.utils.logging import logger
64
64
 
65
65
  def main():
66
66
  parser = argparse.ArgumentParser(description='{step_id} processing step.')
@@ -68,10 +68,10 @@ def main():
68
68
 
69
69
  args = parser.parse_args()
70
70
 
71
- print(clarifai.__version__)
71
+ logger.info(clarifai.__version__)
72
72
 
73
73
  # TODO: Implement your pipeline step logic here
74
- print(f"{step_id} processed: {{args.input_text}}")
74
+ logger.info(f"{step_id} processed: {{args.input_text}}")
75
75
 
76
76
 
77
77
  if __name__ == "__main__":
@@ -8,6 +8,7 @@ from clarifai.client.lister import Lister
8
8
  from clarifai.client.model import Model
9
9
  from clarifai.client.module import Module
10
10
  from clarifai.client.pipeline import Pipeline
11
+ from clarifai.client.pipeline_step import PipelineStep
11
12
  from clarifai.client.search import Search
12
13
  from clarifai.client.user import User
13
14
  from clarifai.client.workflow import Workflow
@@ -20,6 +21,7 @@ __all__ = [
20
21
  'Model',
21
22
  'Workflow',
22
23
  'Pipeline',
24
+ 'PipelineStep',
23
25
  'Module',
24
26
  'Lister',
25
27
  'Dataset',