> ## Documentation Index
> Fetch the complete documentation index at: https://docs.labelbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload conversational text predictions

> How to upload predictions on conversational text data in a model run and sample upload formats.

<CardGroup cols={2}>
  <Card title="Open In Colab" icon="infinity" iconType="solid" href="https://colab.research.google.com/github/Labelbox/labelbox-notebooks/blob/main/prediction_upload/conversational_predictions.ipynb" horizontal />

  <Card title="GitHub" icon="github" iconType="solid" href="https://github.com/Labelbox/labelbox-notebooks/blob/main/prediction_upload/conversational_predictions.ipynb" horizontal />
</CardGroup>

## Supported predictions

To upload predictions in Labelbox, you need to create a predictions payload. In this section, we provide this payload for every supported prediction type.

Labelbox supports two formats for the predictions payload:

* Python annotation types (recommended)
* NDJSON

Both are described below.

### Entity

<CodeGroup>
  ```python Python annotation theme={null}
  ner_prediction = lb_types.ObjectAnnotation(
      name="ner",
      confidence=0.5,
      value=lb_types.ConversationEntity(
          start=0,
          end=8,
          message_id="4"
      )
  )
  ```

  ```python NDJSON theme={null}
  ner_prediction_ndjson = {
    "name": "ner",
    "confidence":0.5,
    "location": {
      "start": 0,
      "end": 8
    },
    "messageId": "4"
  }
  ```
</CodeGroup>

### Global classification: Radio

<CodeGroup>
  ```python Python annotation theme={null}
  radio_prediction = lb_types.ClassificationAnnotation(
      name="radio_question",
      value=lb_types.Radio(answer = lb_types.ClassificationAnswer(name = "second_radio_answer", confidence=0.5))
  )
  ```

  ```python NDJSON theme={null}
  radio_prediction_ndjson = {
    "name": "radio_question",
    "answer": {"name": "second_radio_answer", "confidence": 0.5}
  }
  ```
</CodeGroup>

### Message-based classification: Radio

<CodeGroup>
  ```python Python annotation theme={null}
  radio_prediction = lb_types.ClassificationAnnotation(
      name="radio_convo",
      value=lb_types.Radio(answer = lb_types.ClassificationAnswer(name = "first_radio_answer", confidence=0.5)),
      message_id="0"
  )
  ```

  ```python NDJSON theme={null}
  radio_prediction_ndjson = {
      "name": "radio_convo",
      "answer": {
          "name": "first_radio_answer", "confidence":0.5
      },
      "messageId": "0",
  }
  ```
</CodeGroup>

### Message-based classification: Free-form text

<CodeGroup>
  ```python Python annotation theme={null}
  # Confidence scores are not supported for text predictions
  text_prediction = lb_types.ClassificationAnnotation(
      name="text_convo",
      value=lb_types.Text(answer="the answer to the text questions are right here"),
      message_id="0"
  )
  ```

  ```python NDJSON theme={null}
  text_prediction_ndjson = {
      "name": "text_convo",
      "answer": "the answer to the text questions are right here",
      "messageId": "0"
  }
  ```
</CodeGroup>

### Message-based classification: Checklist

<CodeGroup>
  ```python Python annotation theme={null}
  checklist_prediction= lb_types.ClassificationAnnotation(
    name="checklist_convo", # must match your ontology feature"s name
    value=lb_types.Checklist(
        answer = [
          lb_types.ClassificationAnswer(
              name = "first_checklist_answer", confidence=0.5
          ),
          lb_types.ClassificationAnswer(
              name = "second_checklist_answer", confidence=0.5
          )
        ]
      ),
    message_id="2"
  )
  ```

  ```python NDJSON theme={null}
  checklist_prediction_ndjson = {
      "name": "checklist_convo",
      "answers": [
          {"name": "first_checklist_answer", "confidence":0.5},
          {"name": "second_checklist_answer", "confidence":0.5}
      ],
      "messageId": "2"
  }
  ```
</CodeGroup>

### Message-based nested classifications: Checklist and radio

<CodeGroup>
  ```python Python annotation theme={null}
  nested_checklist_prediction = lb_types.ClassificationAnnotation(
    name="nested_checklist_question",
    message_id="10",
    value=lb_types.Checklist(
      answer=[lb_types.ClassificationAnswer(
        name="first_checklist_answer",
        confidence=0.5, # Confidence scores should be added to the answer 
        classifications=[
          lb_types.ClassificationAnnotation(
            name="sub_checklist_question",
            value=lb_types.Checklist(
              answer=[lb_types.ClassificationAnswer(
              name="first_sub_checklist_answer",
              confidence=0.5 # Confidence scores should be added to the answer 
            )]
          ))
        ]
      )]
    )
  )

  nested_radio_prediction = lb_types.ClassificationAnnotation(
    name="nested_radio_question",
    value=lb_types.Radio(
      answer=lb_types.ClassificationAnswer(
        name="first_radio_answer",
        confidence=0.5, # Confidence scores should be added to the answer 
        classifications=[
          lb_types.ClassificationAnnotation(
            name="sub_radio_question",
            value=lb_types.Radio(
              answer=lb_types.ClassificationAnswer(
                name="first_sub_radio_answer",
                confidence=0.5 # Confidence scores should be added to the answer
              )
            )
          )
        ]
      )
    )
  )
  ```

  ```python NDJSON theme={null}
  nested_checklist_prediction_ndjson = {
    "name": "nested_checklist_question",
    "messageId": "10",
    "answer": [{
        "name": "first_checklist_answer",
        "confidence": 0.5, # Confidence scores should be added to the answer
        "classifications" : [
          {
            "name": "sub_checklist_question",
            "answer": {
              "name": "first_sub_checklist_answer",
              "confidence": 0.5, # Confidence scores should be added to the answer
            }
          }
        ]
    }]
  }

  nested_radio_prediction_ndjson = {
    "name": "nested_radio_question",
    "answer": {
        "name": "first_radio_answer",
        "confidence": 0.5,
        "classifications": [{
            "name":"sub_radio_question",
            "answer": { "name" : "first_sub_radio_answer",
                       "confidence": 0.5}
          }]
      }
  }
  ```
</CodeGroup>

## End-to-end example: Upload predictions to a model run

Here are the steps to upload predictions to a model run:

### Before you start

You will need to import these libraries to use the code examples in this section:

<CodeGroup>
  ```python Python theme={null}
  import labelbox as lb
  import labelbox.types as lb_types
  import uuid
  ```
</CodeGroup>

Replace the value of `API_KEY` with a valid [API key](/reference/create-api-key) to connect to the Labelbox client.

<CodeGroup>
  ```python Python theme={null}
  API_KEY = None
  client = lb.Client(API_KEY)
  ```
</CodeGroup>

### Step 1: Import data rows into Catalog

<CodeGroup>
  ```python Python theme={null}
  global_key = "conversation-1.json"

  asset = {
    "row_data": "https://storage.googleapis.com/labelbox-developer-testing-assets/conversational_text/1000-conversations/conversation-1.json",
    "global_key": global_key,
  }

  dataset = client.create_dataset(name="conversational_annotation_import_demo_dataset")

  task = dataset.create_data_rows([asset])
  task.wait_till_done()

  print("Errors:", task.errors)
  print("Failed data rows: ", task.failed_data_rows)
  ```
</CodeGroup>

### Step 2: Create/select an ontology for your model predictions

For best results, verify your ontology before submitting a model run. Verify that:

* Your ontology supports all features and classifications that might be needed during the model run.
* Tool names and classification instructions match the `name` and `instructions` fields in your annotation payloads.

This helps ensure that feature schemas match your intentions.

<CodeGroup>
  ```python Python expandable theme={null}
  ontology_builder = lb.OntologyBuilder(
    tools=[
      lb.Tool(tool=lb.Tool.Type.NER,name="ner")
      ],
    classifications=[
      lb.Classification(
        class_type=lb.Classification.Type.TEXT,
        scope=lb.Classification.Scope.INDEX,
        instructions="text_convo"),
      lb.Classification(
        class_type=lb.Classification.Type.CHECKLIST,
        scope=lb.Classification.Scope.INDEX,
        instructions="checklist_convo",
        options=[
          lb.Option(value="first_checklist_answer"),
          lb.Option(value="second_checklist_answer")
        ]
      ),
      lb.Classification(
        class_type=lb.Classification.Type.RADIO,
        instructions="radio_convo",
        scope=lb.Classification.Scope.INDEX,
        options=[
          lb.Option(value="first_radio_answer"),
          lb.Option(value="second_radio_answer")
        ]
      ),
      lb.Classification(
        class_type=lb.Classification.Type.CHECKLIST,
        name="nested_checklist_question",
        scope = lb.Classification.Scope.INDEX,
        options=[
            lb.Option("first_checklist_answer",
              options=[
                lb.Classification(
                    class_type=lb.Classification.Type.CHECKLIST,
                    name="sub_checklist_question",
                    options=[lb.Option("first_sub_checklist_answer")]
                )
            ])
        ]
      ),
      lb.Classification(
          class_type=lb.Classification.Type.RADIO,
          name="nested_radio_question",
          scope = lb.Classification.Scope.GLOBAL,
          options=[
              lb.Option("first_radio_answer",
                  options=[
                      lb.Classification(
                          class_type=lb.Classification.Type.RADIO,
                          name="sub_radio_question",
                          options=[lb.Option("first_sub_radio_answer")]
                      )
                  ])
            ]
      )
    ]
  )

  ontology = client.create_ontology("Ontology Conversation Annotations", ontology_builder.asdict())
  ```
</CodeGroup>

### Step 3: Create a model and a model run

<CodeGroup>
  ```python Python theme={null}
  # create model
  model = client.create_model(name="Conversational_model_run_"+ str(uuid.uuid4()),
                              ontology_id=ontology.uid)
  # create model run
  model_run = model.create_model_run("iteration 1")

  ```
</CodeGroup>

### Step 4: Send data rows to the model run

<CodeGroup>
  ```python Python theme={null}
  model_run.upsert_data_rows(global_keys=[global_key])
  ```
</CodeGroup>

### Step 5: Create the predictions payload

Create the prediction payload using the code snippets in the section above.

Labelbox supports two formats for the annotations payload: NDJSON and Python annotation types. Both are described below to compose your annotations into labels attached to the data rows.

The resulting payload should have exactly the same content for the annotations supported by both formats.

#### Python annotations

<CodeGroup>
  ```python Python theme={null}
  label_prediction = []
  label_prediction.append(
    lb_types.Label(
  		data= {"global_key": global_key}),
      annotations=[
        ner_prediction,
        checklist_prediction,
        text_prediction,
        radio_prediction,
        nested_checklist_prediction,
        nested_radio_prediction
      ]
    )
  )
  ```
</CodeGroup>

#### NDJSON

<CodeGroup>
  ```python Python theme={null}
  label_prediction_ndjson = []
  for annotations in [
      ner_prediction_ndjson,
      text_prediction_ndjson,
      checklist_prediction_ndjson,
      radio_prediction_ndjson,
      nested_checklist_prediction_ndjson,
      nested_radio_prediction_ndjson
      ]:
    annotations.update({
        "dataRow": {
            "globalKey": global_key
        }
    })
    label_prediction_ndjson.append(annotations)
  ```
</CodeGroup>

### Step 6: Upload the predictions payload to the model run

<CodeGroup>
  ```python Python theme={null}
  # Upload the prediction label to the Model Run
  upload_job_prediction = model_run.add_predictions(
      name="prediction_upload_job"+str(uuid.uuid4()),
      predictions=label_prediction)

  # Errors will appear for annotation uploads that failed.

  print("Errors:", upload_job_prediction.errors)
  print("Status of uploads: ", upload_job_prediction.statuses)

  ```
</CodeGroup>

### Step 7: Send annotations to the model run

To send annotations to a model run, we must first import them into a project, create a label payload and then send them to the model run.

<CodeGroup>
  ```python Python theme={null}
  # 7.1 Create a labelbox project
  project = client.create_project(name="Conversational Text Prediction Import Demo",
                                      media_type=lb.MediaType.Conversational)
  project.connect_ontology(ontology)

  # 7.2 Create a batch to send to the project
  project.create_batch(
    "batch_convo_prediction_demo", # Each batch in a project must have a unique name
    global_keys=[global_key], # Paginated collection of data row objects, list of data row ids or global keys
    priority=5 # priority between 1(Highest) - 5(lowest)
  )

  # 7.3 Create the annotations payload
  ner_annotation = lb_types.ObjectAnnotation(
      name="ner",
      value=lb_types.ConversationEntity(
          start=0,
          end=8,
          message_id="4"
      )
  )

  text_annotation = lb_types.ClassificationAnnotation(
      name="text_convo",
      value=lb_types.Text(answer="the answer to the text questions are right here"),
      message_id="0"
  )

  checklist_annotation= lb_types.ClassificationAnnotation(
    name="checklist_convo", # must match your ontology feature"s name
    value=lb_types.Checklist(
        answer = [
          lb_types.ClassificationAnswer(
              name = "first_checklist_answer"
          ),
          lb_types.ClassificationAnswer(
              name = "second_checklist_answer"
          )
        ]
      ),
    message_id="2"
   )

  radio_annotation = lb_types.ClassificationAnnotation(
      name="radio_convo",
      value=lb_types.Radio(answer = lb_types.ClassificationAnswer(name = "first_radio_answer")),
      message_id="0"
  )

  nested_checklist_annotation = lb_types.ClassificationAnnotation(
    name="nested_checklist_question",
    message_id="10",
    value=lb_types.Checklist(
      answer=[lb_types.ClassificationAnswer(
        name="first_checklist_answer",
        classifications=[
          lb_types.ClassificationAnnotation(
            name="sub_checklist_question",
            value=lb_types.Checklist(
              answer=[lb_types.ClassificationAnswer(
              name="first_sub_checklist_answer"
            )]
          ))
        ]
      )]
    )
  )

  nested_radio_annotation = lb_types.ClassificationAnnotation(
    name="nested_radio_question",
    value=lb_types.Radio(
      answer=lb_types.ClassificationAnswer(
        name="first_radio_answer",
        classifications=[
          lb_types.ClassificationAnnotation(
            name="sub_radio_question",
            value=lb_types.Radio(
              answer=lb_types.ClassificationAnswer(
                name="first_sub_radio_answer"
              )
            )
          )
        ]
      )
    )
  )

  # 7.4 Create the label object
  label = []
  label.append(
    lb_types.Label(
  		data= {"global_key": global_key},
      annotations=[
        ner_annotation,
        text_annotation,
        checklist_annotation,
        radio_annotation,
        nested_radio_annotation,
        nested_checklist_annotation
      ]
    )
  )

  # 7.5 Upload annotations to the project using label import
  upload_job_annotation = lb.LabelImport.create_from_objects(
      client = client,
      project_id = project.uid,
      name="text_label_import_job"+ str(uuid.uuid4()),
      labels=label)

  upload_job_annotation.wait_until_done()

  # Errors will appear for annotation uploads that failed.
  print("Errors:", upload_job_annotation.errors)
  print("Status of uploads: ", upload_job_annotation.statuses)

  # 7.6 Send the annotations to the model run
  # get the labels from the project
  model_run.upsert_labels(project_id=project.uid)
  ```
</CodeGroup>
