Skip to main content

Manage Inputs

Learn how to use our API to manage, organize, and process your inputs


You can manage inputs on the Clarifai platform by organizing, updating, deleting, and performing various data processing tasks.

Whether you're working with images, text, or videos, the platform provides powerful capabilities to help you maintain full control over your inputs throughout their lifecycle.

info

Before using the Python SDK, Node.js SDK, or any of our gRPC clients, ensure they are properly installed on your machine. Refer to their respective installation guides for instructions on how to install and initialize them.

List Inputs

List All Inputs

You can retrieve all inputs available in your app. If you added inputs with concepts, they will be returned in the response as well.

Note that this request supports pagination, allowing you to navigate through large sets of inputs efficiently.

from clarifai.client.user import User

# Create the input object
input_obj = User(user_id="user_id").app(app_id="test_app", pat="YOUR_PAT").inputs()
# list the inputs with pagination
all_inputs = list(input_obj.list_inputs(page_no=1,per_page=3))
print(all_inputs)
Output
[id: "demo1"
data {
image {
url: "https://samples.clarifai.com/metro-north.jpg"
hosted {
prefix: "https://data.clarifai.com"
suffix: "users/8tzpjy1a841y/apps/test_app/inputs/image/140c856dc82565d2c4d6ea720fceff78"
sizes: "orig"
sizes: "tiny"
sizes: "small"
sizes: "large"
crossorigin: "use-credentials"
}
image_info {
width: 512
height: 384
format: "JPEG"
color_mode: "YUV"
}
}
}
created_at {
seconds: 1705917660
nanos: 789409000
}
...
code: INPUT_DOWNLOAD_SUCCESS
description: "Download complete"
}
]

List Inputs (Streaming)

This is another method for listing inputs, which was built to scalably list an app's inputs in an iterative / streaming fashion. StreamInputs will return per_page number of inputs from a certain input onward, controlled by the optional last_id parameter (defaults to the first input).

By default, the stream will return inputs from oldest to newest. Set the descending field to true to reverse that order.

###############################################################
# In this section, we set the user authentication and app ID.
# Change these strings to run your own example.
###############################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

# To start from beginning, do not provide the last_id parameter.
stream_inputs_response = stub.StreamInputs(
service_pb2.StreamInputsRequest(
user_app_id=userDataObject,
per_page=5,
# descending = True # Set to reverse order
),
metadata=metadata
)

if stream_inputs_response.status.code != status_code_pb2.SUCCESS:
print(stream_inputs_response.status)
raise Exception("Stream inputs failed, status: " + stream_inputs_response.status.description)

print("First response (starting from the first input):")
for input_object in stream_inputs_response.inputs:
print("\t" + input_object.id)

last_id = stream_inputs_response.inputs[-1].id

# Set last_id to get the next set of inputs. The returned inputs will not include the last_id input.
stream_inputs_response = stub.StreamInputs(
service_pb2.StreamInputsRequest(
user_app_id=userDataObject,
per_page=5,
last_id=last_id
),
metadata=metadata
)

print(f"Second response (first input is the one following input ID {last_id}):")
for input_object in stream_inputs_response.inputs:
print("\t" + input_object.id)

Get Inputs

Get Input by ID

If you'd like to get the details of a specific input by its id, you can do that as well.

###############################################################################
# In this section, we set the user authentication, app ID, and the input's ID
# Change these strings to run your own example.
###############################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change this ID to whatever input you want its details
INPUT_ID = 'eec128fd81974543bafff48702edca4d'

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

get_input_response = stub.GetInput(
service_pb2.GetInputRequest(
user_app_id=userDataObject,
input_id=INPUT_ID
),
metadata=metadata
)

if get_input_response.status.code != status_code_pb2.SUCCESS:
print(get_input_response.status)
raise Exception("Get input failed, status: " + get_input_response.status.description)

input_object = get_input_response.input
print(input_object)

Get Inputs' Status

If you add inputs in bulk, they will be procesed in the background. You can get the status of all your inputs (processed, to_process, and errors) like this:

##################################################################
# In this section, we set the user authentication and the app ID.
# Change these strings to run your own example.
##################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

get_input_count_response = stub.GetInputCount(
service_pb2.GetInputCountRequest(
user_app_id=userDataObject
),
metadata=metadata
)

if get_input_count_response.status.code != status_code_pb2.SUCCESS:
print(get_input_count_response.status)
raise Exception("Get input count failed, status: " + get_input_count_response.status.description)

counts = get_input_count_response.counts
print(counts)

Download Inputs

Below is an example of how to download inputs from your app.

from clarifai.client.input import Inputs

# Initialize the Inputs object with user and app IDs
input_object = Inputs(user_id="YOUR_USER_ID_HERE", app_id="YOUR_APP_ID_HERE", pat="YOUR_PAT_HERE")

# Download inputs
input_object.download_inputs(list(input_object.list_inputs()))

Patch Inputs

You can apply patch operations to an input, allowing for the merging or removal of items. By default, these actions overwrite existing data, but they behave differently when handling lists of objects.

  • The merge action replaces a key:value pair with a key:new_value, or appends new values to an existing list. When dealing with dictionaries, it merges entries that share the same id field.

  • The remove action replaces a key:value pair with a key:new_value, or removes any items from a list that match the IDs of the provided values.

  • The overwrite action fully replaces an existing object with a new one.

Patch Metadata

Here is an example of how to patch the metadata of an input.

from clarifai.client.input import Inputs
from google.protobuf.struct_pb2 import Struct

# Metadata structure should be of Struct, so we create it, add the necessary details and provide it to input proto
metadata = Struct()
metadata.update({"split": "test"})

# Initialize the Inputs object with user and app IDs
input_object = Inputs(user_id="YOUR_USER_ID_HERE", app_id="YOUR_APP_ID_HERE", pat="YOUR_PAT_HERE")

new_input = input_object._get_proto(input_id="YOUR_INPUT_ID_HERE", metadata= metadata)

# Update the metadata
input_object.patch_inputs([new_input],action="merge")

# Overwrite the metadata
input_object.patch_inputs([new_input],action='overwrite')

Patch Bounding Box Annotation

Here is an example of how to patch a bounding box annotation on an input.

from clarifai.client.input import Inputs

# Initialize the Inputs object with user and app IDs
input_object = Inputs(user_id="YOUR_USER_ID_HERE", app_id="YOUR_APP_ID_HERE", pat="YOUR_PAT_HERE")

# Upload the image with a specific input ID
input_object.upload_from_url(input_id="bbox", image_url="https://samples.clarifai.com/BarackObama.jpg")

# Upload initial bounding box annotations
bbox_points = [.1, .1, .8, .9] # Coordinates of the bounding box
annotation = input_object.get_bbox_proto(input_id="bbox", label="face", bbox=bbox_points, label_id="id-face", annot_id="demo")
input_object.upload_annotations([annotation])

# Update existing bounding box annotations with new coordinates
bbox_points = [.35, .45, .6, .7] # New coordinates of the bounding box
annotation = input_object.get_bbox_proto(input_id="bbox", label="face", bbox=bbox_points, label_id="id-face", annot_id="demo")
input_object.patch_annotations([annotation], action='merge')

# Remove the bounding box annotations
bbox_points = [.3, .3, .6, .7] # Coordinates of the bounding box to be removed
annotation = input_object.get_bbox_proto(input_id="bbox", label="face", bbox=bbox_points, label_id="id-face", annot_id="demo")
input_object.patch_annotations([annotation], action='remove')

Patch Polygon Annotation

Here is an example of how to patch a polygon annotation on an input.

from clarifai.client.input import Inputs

# Initialize the Inputs object with user and app IDs
input_object = Inputs(user_id="YOUR_USER_ID_HERE", app_id="YOUR_APP_ID_HERE", pat="YOUR_PAT_HERE")

# Upload the image with a specific input ID
input_object.upload_from_url(input_id="polygon", image_url="https://samples.clarifai.com/BarackObama.jpg")

# Upload initial polygon annotations
polygon_pts = [[.1,.1],[.1,.9],[.9,.9],[.9,.1]] # Coordinates of the polygon
annotation = input_object.get_mask_proto(input_id="polygon", label="label", polygons=polygon_pts, annot_id="annotation_id")
input_object.upload_annotations([annotation])

# Update existing polygon annotations with new coordinates
polygon_pts = [[.15,.15],[.15,.95],[.95,.95],[.95,.15]] # New coordinates of the polygon
annotation = input_object.get_mask_proto(input_id="polygon", label="label", polygons=polygon_pts, annot_id="annotation_id")
input_object.patch_annotations([annotation],action='merge')

# Remove the polygon annotations
polygon_pts = [[.3,.3],[.3,.7],[.8,.8],[.7,.3]] # Coordinates of the polygon to be removed
annotation = input_object.get_mask_proto(input_id="polygon", label="label", polygons=polygon_pts, annot_id="annotation_id")
input_object.patch_annotations([annotation],action='remove')

Update Input With Concepts

To update an input with a new concept, or to change a concept value from true/false, you can do the following:

from clarifai.client.input import Inputs

# Initialize the Inputs object with user and app IDs
input_object = Inputs(user_id="YOUR_USER_ID_HERE", app_id="YOUR_APP_ID_HERE", pat="YOUR_PAT_HERE")

# This example changes the existing concept label "id-face" to "obama_face"
input_object.patch_concepts(
concept_ids=["id-face"], # The ID of the concept you want to update
labels=["obama_face"], # The new label name to overwrite the existing one
values=[],
action='overwrite' # Currently, only the `overwrite` action is supported
)

Bulk Update Inputs With Concepts

You can update existing inputs using their ids. This is useful if you'd like to add concepts to inputs after they have already been added.

Below is an example of how to update multiple inputs with concepts at once.

################################################################################
# In this section, we set the user authentication, app ID, and the inputs and
# concepts IDs we want to update. Change these strings to run your own example.
################################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change these based on the updates you want to make
INPUT_ID_1 = '2e9c4a86555d40ffb47c7b045d7e3048'
INPUT_ID_2 = '52b467c2005946cbbbe7a5eec76e29cf'
CONCEPT_ID_1 = 'tree'
CONCEPT_ID_2 = 'water'
CONCEPT_ID_3 = 'animal'
CONCEPT_ID_4 = 'fruit'

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

patch_inputs_response = stub.PatchInputs(
service_pb2.PatchInputsRequest(
user_app_id=userDataObject,
action="merge", # Supported actions: overwrite, merge, remove.
inputs=[
resources_pb2.Input(
id=INPUT_ID_1,
data=resources_pb2.Data(
concepts=[
resources_pb2.Concept(id=CONCEPT_ID_1, value=1.), # 1 means true, this concept is present.
resources_pb2.Concept(id=CONCEPT_ID_2, value=0.) # 0 means false, this concept is not present.
]
)
),
resources_pb2.Input(
id=INPUT_ID_2,
data=resources_pb2.Data(
concepts=[
resources_pb2.Concept(id=CONCEPT_ID_3, value=1.),
resources_pb2.Concept(id=CONCEPT_ID_4, value=0.)
]
)
),
]
),
metadata=metadata
)

if patch_inputs_response.status.code != status_code_pb2.SUCCESS:
print(patch_inputs_response.status)
raise Exception("Patch inputs failed, status: " + patch_inputs_response.status.description)

Bulk Delete Input Annotations

Below is an example of how to delete all the annotations associated with a given input by setting the input ID(s).

The annotation_ids parameter is optional. However, if provided, the number and order of annotation_ids must match the corresponding input_ids.

from clarifai.client.input import Inputs

# Initialize the Inputs object with user and app IDs
input_object = Inputs(user_id="YOUR_USER_ID_HERE", app_id="YOUR_APP_ID_HERE", pat="YOUR_PAT_HERE")

# Bulk delete annotations
input_object.delete_annotations(input_ids=["input_id1", "input_id1", "input_id2"], annotation_ids=["annot_id11", "annot_id12", "annot_id21"])

Delete Inputs

caution

Be certain that you want to delete a particular input as the operation cannot be undone.

Delete Concepts From an Input

To remove concepts that were already added to an input, you can do this:

##############################################################################
# In this section, we set the user authentication, app ID, and the input and
# concept ID. Change these strings to run your own example.
##############################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change these based on the concept you want to remove
INPUT_ID = '2e9c4a86555d40ffb47c7b045d7e3048'
CONCEPT_ID = 'water'

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

patch_inputs_response = stub.PatchInputs(
service_pb2.PatchInputsRequest(
user_app_id=userDataObject,
action="remove", # Supported actions: overwrite, merge, remove.
inputs=[
resources_pb2.Input(
id=INPUT_ID,
data=resources_pb2.Data(
concepts=[
# We're removing the concept, so there's no need to specify
# the concept value.
resources_pb2.Concept(id=CONCEPT_ID),
]
)
)
]
),
metadata=metadata
)

if patch_inputs_response.status.code != status_code_pb2.SUCCESS:
print(patch_inputs_response.status)
raise Exception("Patch inputs failed, status: " + patch_inputs_response.status.description)

Bulk Delete Concepts From a List of Inputs

Below is an example of how to bulk delete multiple concepts from a list of inputs.

##############################################################################
# In this section, we set the user authentication, app ID, and the inputs and
# concepts IDs. Change these strings to run your own example.
##############################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change these based on the concepts you want to remove
INPUT_ID_1 = '2e9c4a86555d40ffb47c7b045d7e3048'
INPUT_ID_2 = '52b467c2005946cbbbe7a5eec76e29cf'
CONCEPT_ID_1 = 'tree'
CONCEPT_ID_2 = 'water'
CONCEPT_ID_3 = 'animal'
CONCEPT_ID_4 = 'fruit'

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

patch_inputs_response = stub.PatchInputs(
service_pb2.PatchInputsRequest(
user_app_id=userDataObject,
action="remove", # Supported actions: overwrite, merge, remove.
inputs=[
resources_pb2.Input(
id=INPUT_ID_1,
data=resources_pb2.Data(
concepts=[
# We're removing the concepts, so there's no need to specify
# the concept value.
resources_pb2.Concept(id=CONCEPT_ID_1),
resources_pb2.Concept(id=CONCEPT_ID_2),
]
)
),
resources_pb2.Input(
id=INPUT_ID_2,
data=resources_pb2.Data(
concepts=[
resources_pb2.Concept(id=CONCEPT_ID_3),
resources_pb2.Concept(id=CONCEPT_ID_4),
]
)
),
]
),
metadata=metadata
)

if patch_inputs_response.status.code != status_code_pb2.SUCCESS:
print(patch_inputs_response.status)
raise Exception("Patch inputs failed, status: " + patch_inputs_response.status.description)

Delete Input by ID

Below is an example of how to delete a single input by its id.

##############################################################################
# In this section, we set the user authentication, app ID, and the ID of the
# input we want to delete. Change these strings to run your own example.
##############################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change this based on the input you want to delete
INPUT_ID = '2e9c4a86555d40ffb47c7b045d7e3048'

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

delete_input_response = stub.DeleteInput(
service_pb2.DeleteInputRequest(
user_app_id=userDataObject,
input_id=INPUT_ID
),
metadata=metadata
)

if delete_input_response.status.code != status_code_pb2.SUCCESS:
print(delete_input_response.status)
raise Exception("Delete input failed, status: " + delete_input_response.status.description)

Delete a List of Inputs

You can also delete multiple inputs in one API call. This will happen asynchronously.

info

We currently support a batch size of 128 inputs per request. So, you can provide a list of 128 input IDs and delete them in one API call.

##############################################################################
# In this section, we set the user authentication, app ID, and the IDs of the
# inputs we want to delete. Change these strings to run your own example.
##############################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change these based on the inputs you want to delete
INPUT_ID_1 = '97eb76d22e964c7cbbf06a51532c6fbe'
INPUT_ID_2 = '86b1272feabb45d4bcd2de51eedd729b'

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID)

delete_inputs_response = stub.DeleteInputs(
service_pb2.DeleteInputsRequest(
user_app_id=userDataObject,
ids=[INPUT_ID_1, INPUT_ID_2]
),
metadata=metadata
)

if delete_inputs_response.status.code != status_code_pb2.SUCCESS:
print(delete_inputs_response.status)
raise Exception("Delete input failed, status: " + delete_inputs_response.status.description)

Delete All Inputs

Below is an example of how to delete all inputs from your app.

from clarifai.client.user import User

input_obj = User(user_id="user_id", pat="YOUR_PAT").app(app_id="test_app").inputs()
# You can also provide the inputs ids as parameters in delete_inputs function
input_obj.delete_inputs(list(input_obj.list_inputs()))
Output
2024-01-16 14:44:28 INFO     clarifai.client.input:                                                    input.py:732

Inputs Deleted

code: SUCCESS

description: "Ok"

req_id: "4ae26cd15c7da98a1c2d3647b03d2768"