> ## 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.

# Ontology

> Developer guide for creating, modifying, and connecting ontologies via the Python SDK.

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

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

## Client

<CodeGroup>
  ```python Python theme={null}
  import labelbox as lb
  import labelbox.data.annotation_types as lb_types
  client = lb.Client(api_key="<YOUR_API_KEY>")
  ```
</CodeGroup>

## Create an ontology

Each `Tool` and `Classification` type requires a specific value to be passed when creating the feature.

| Feature                    | Class            | Value                      |
| -------------------------- | ---------------- | -------------------------- |
| Bounding box               | `Tool`           | `BBOX`                     |
| Polygon                    | `Tool`           | `POLYGON`                  |
| Polyline                   | `Tool`           | `LINE`                     |
| Point                      | `Tool`           | `POINT`                    |
| Segmentation mask          | `Tool`           | `RASTER_SEGMENTATION`      |
| Relationship               | `Tool`           | `RELATIONSHIP`             |
| Entity                     | `Tool`           | `NER`                      |
| Message ranking            | `Tool`           | `MESSAGE_RANKING`          |
| Single message selection   | `Tool`           | `MESSAGE_SINGLE_SELECTION` |
| Multiple message selection | `Tool`           | `MESSAGE_MULTI_SELECTION`  |
| Message step reasoning     | `Tool`           | `STEP_REASONING`           |
| Fact-checking              | `Tool`           | `FACT_CHECKING`            |
| Prompt rating              | `Tool`           | `PROMPT_ISSUE`             |
| Radio                      | `Classification` | `RADIO`                    |
| Checklist                  | `Classification` | `CHECKLIST`                |
| Text                       | `Classification` | `TEXT`                     |

When you create an ontology, specify the `media_type` parameter, which represents the modality of the data rows that the ontology will be used to label. Certain features are only compatible with certain media types.

<Warning>
  ### Specify an ontology media type

  The `media_type` parameter of `client.create_ontology` defaults to `None`, but it's highly recommended to specify one for validation and error handling.
</Warning>

The `media_type` parameter takes the following values:

* `lb.MediaType.Audio`
* `lb.MediaType.Conversational`
* `lb.MediaType.Document`
* `lb.MediaType.Geospatial_Tile`
* `lb.MediaType.Html`
* `lb.MediaType.Image`
* `lb.MediaType.Simple_Tile`
* `lb.MediaType.Text`
* `lb.MediaType.Video`

### Create ontologies from new features

You can define new features to build new ontologies. The following code sample shows how to create simple features for upserting into ontologies. To learn more about creating features, see [Features](/reference/feature#create-a-feature).

<CodeGroup>
  ```python Create features theme={null}
  object_features = [
      lb.Tool(
          tool=lb.Tool.Type.BBOX,
          name="regulatory-sign",
          color="#ff0000",
      )
  ]

  classification_features = [
  lb.Classification(
  class_type=lb.Classification.Type.CHECKLIST,
  name="Quality Issues",
  options=[
  lb.Option(value="blurry", label="Blurry"),
  lb.Option(value="distorted", label="Distorted")
  ]
  )

  ]

  ```
</CodeGroup>

You can then create an ontology with your defined features either using `ontology_builder` or `client.create_ontology_from_feature_schemas()`.

<CodeGroup>
  ```python ontology_builder theme={null}
  ontology_builder = lb.OntologyBuilder(
      tools=object_features,
      classifications=classification_features
  )

  ontology = client.create_ontology(
    "Ontology from new features",
    ontology_builder.asdict(),
    media_type=lb.MediaType.Image
  )
  ```

  ```python create_ontology_from_feature_schemas theme={null}
  # First create the feature schema
  feature_schema_cat = client.create_feature_schema(feature_schema_cat_normalized)
  # When we create the ontology it will not re-create the feature schema
  print(feature_schema_cat.uid)
  ontology = client.create_ontology_from_feature_schemas(ontology_name,
                                                         [feature_schema_cat.uid])
  ```
</CodeGroup>

For more complex ontology creation examples, see [Ontology examples guide](/reference/ontology-examples) .

### Create from normalized JSON format

* Users can create ontologies from a JSON definition of the ontology.
* Each tool type requires a specific value to be passed:

| Tool              | Value                 |
| ----------------- | --------------------- |
| Bounding box      | `rectangle`           |
| Polygon           | `polygon`             |
| Polyline          | `line`                |
| Point             | `point`               |
| Segmentation mask | `raster-segmentation` |
| Entity            | `named-entity`        |

<CodeGroup>
  ```python Python theme={null}
  # This automatically creates new feature schema
  ontology_name = "sdk-ontology"
  feature_schema_cat_normalized = {
      'tool': 'polygon',
      'name': 'cat',
      'color': 'black'
  }

  ontology_normalized_json = {
  "tools": [feature_schema_cat_normalized],
  "classifications": []
  }
  ontology = client.create_ontology(name=ontology_name,
  normalized=ontology_normalized_json,
  media_type=lb.MediaType.Image)

  ```
</CodeGroup>

### Create from existing features

If you already have features created, you can query them by name or by schema id. Re-using an existing feature is highly recommended.

<CodeGroup>
  ```python Python theme={null}
  ## Search feature by name in your org
  regulatory_sign_feature_schema = next(client.get_feature_schemas("regulatory-sign"))
  classification_feature = next(client.get_feature_schemas("Quality Issues"))

  ## Get feature by feature schema ID. Alternatively you can get this from the UI
  regulatory_sign_feature_schema = client.get_feature_schema("FEATURE_SCHEMA_ID")

  ontology = client.create_ontology_from_feature_schemas("Ontology from existing features", [regulatory_sign_feature_schema.uid, classification_feature.uid], media_type=MediaType.Image)
  ```
</CodeGroup>

### Create a nested ontology

You can create a child feature nested under a parent feature. Only classification features can be children of a nested ontology. For instance, if you want to create an ontology where a bounding box has a radio sub-classification, you will add a `classifications`field that contains a list of classification features as children.

<CodeGroup>
  ```python Tool with subclassification theme={null}
  bbox_with_sub_classification = lb.Tool(tool=lb.Tool.Type.BBOX, name="cat",
           classifications=[
              lb.Classification(class_type=lb.Classification.Type.RADIO, name="radio", options=[
                  lb.Option(value="long-fur"),
                  lb.Option(value="short-fur")
              ])
           ])

  ontology_builder = lb.OntologyBuilder(tools=[
  bbox_with_sub_classification
  ])

  ontology = client.create_ontology("Simple nested ontology", ontology_builder.asdict(), media_type=MediaType.Image)

  ```

  ```python Classification with subclassification theme={null}
  radio_with_sub_classification = Classification(
        class_type=Classification.Type.RADIO,
        instructions="radio_question_sub",
        options=[
          Option(value="first_radio_answer",
                 options=[
                     Classification(
                      class_type=Classification.Type.RADIO,
                      instructions="sub_radio_question",
                      options=[
                        Option(value="first_sub_radio_answer"),
                        Option(value="second_sub_radio_answer")
                      ]
                    ),
              ])],
      )

  ontology_builder = OntologyBuilder(classifications=[
      sub_radio_classification
  ])

  ontology = client.create_ontology("Simple nested ontology", ontology_builder.asdict())
  ```
</CodeGroup>

## Get ontologies

<CodeGroup>
  ```python Python theme={null}
  # get by ID
  ontology = client.get_ontology("<ontology_id>")

  # get by name

  ontology = next(client.get_ontologies("<ontology_name>"))

  # get multiple ontologies by keyword

  ontologies = client.get_ontologies(name_contains="<keyword>")

  ```
</CodeGroup>

### Check if a feature is archived in an ontology

<CodeGroup>
  ```python Python theme={null}
  client.is_feature_schema_archived("<ontology_id>", "<feature_schema_id>")
  ```
</CodeGroup>

### Get all unused ontologies

<CodeGroup>
  ```python Python theme={null}
  client.get_unused_ontologies()
  ```
</CodeGroup>

### Delete an unused ontology

<CodeGroup>
  ```python Python theme={null}
  client.delete_unused_ontology("<ontology_id>")
  ```
</CodeGroup>

## Connect an ontology to a project

<CodeGroup>
  ```python Python theme={null}
  # get (or create) a project
  project = client.get_project("<project_id>")

  # get (or create) an ontology

  ontology = client.get_ontology("<ontology_id>")

  # the argument must be an object of the Ontology class

  project.connect_ontology(ontology)

  ```
</CodeGroup>

## Methods

### Get the tools

<CodeGroup>
  ```python Python theme={null}
  tools = ontology.tools()

  for tool in tools:
  print(tool)

  ```
</CodeGroup>

### Get the classifications

<CodeGroup>
  ```python Python theme={null}
  classifications = ontology.classifications()

  for classification in classifications:
  print(classification)

  ```
</CodeGroup>

## Attributes

<CodeGroup>
  ```python Python theme={null}
  # name (str)
  ontology.name

  # description (str)

  ontology.description

  # updated at (datetime)

  ontology.updated_at

  # created at (datetime)

  ontology.created_at

  # normalized output of the ontology (JSON)

  ontology.normalized

  # count of object tools in the ontology (int)

  ontology.object_schema_count

  # count of classifications in the ontology (int)

  ontology.classification_schema_count

  # created by (relationship to User object)

  user = ontology.created_by()

  ```
</CodeGroup>
