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

# Features

> Developer guide for creating and modifying features via the Python SDK.

View [Features](/docs/working-with-features) guide page for feature schema definitions and details.

## Create a feature

**Features** define the **tools** and **classifications** used to annotate your data. To create features for use in an ontology, use the `client.create_feature_schema()` method.

<CodeGroup>
  ```python Tool theme={null}
  from labelbox import Tool

  # Defining tool features
  # required is an optional field defaults to False if not specified
  bbox_tool = Tool(tool=Tool.Type.BBOX, name="dog_box", required=True)
  poly_tool = Tool(tool=Tool.Type.POLYGON, name="dog_poly")
  seg_tool = Tool(tool=Tool.Type.SEGMENTATION, name="dog_seg")
  point_tool = Tool(tool=Tool.Type.POINT, name="dog_center")
  line_tool = Tool(tool=Tool.Type.LINE, name="dog_orientation")
  ner_tool = Tool(tool=Tool.Type.NER, name="dog_reference", required=True)

  # Creating feature schema for each defined tool
  feature_schema_bbox = client.create_feature_schema(bbox_tool.asdict())
  feature_schema_poly = client.create_feature_schema(poly_tool.asdict())
  feature_schema_seg= client.create_feature_schema(seg_tool.asdict())
  feature_schema_tool = client.create_feature_schema(point_tool.asdict())
  feature_schema_line = client.create_feature_schema(line_tool.asdict())
  feature_schema_ner = client.create_feature_schema(ner_tool.asdict())
  ```

  ```python Classification theme={null}

  # Defining classification features
  # required is an optional field defaults to False if not specified
  from labelbox import Classification, Option

  text_classification = Classification(class_type=Classification.Type.TEXT,
                                       name="dog_name", required=True)
  radio_classification = Classification(class_type=Classification.Type.RADIO,
                                        name="dog_breed",
                                        options=[Option("poodle")], required=True)
  checklist_classification = Classification(
      class_type=Classification.Type.CHECKLIST,
      name="background",
      options=[Option("at_park"), Option("has_leash")])
  nested_classification = Classification(
      class_type=Classification.Type.CHECKLIST,
      name="Appliance Features",
      options=[
          Option(
              "HasWarranty",
              options=[  # Nested options
                  Option("1 Year"),
                  Option("2 Years"),
                  Option("5 Years")
              ]
          ),
          Option("EnergyEfficient"),
          Option("SmartHomeCompatible")
      ]
  )

  # Creating feature schema for each defined classification
  feature_schema_text = client.create_feature_schema(text_classification.asdict())
  feature_schema_radio = client.create_feature_schema(radio_classification.asdict())
  feature_schema_checklist = client.create_feature_schema(checklist_classification.asdict())
  feature_schema_nested = client.create_feature_schema(nested_classification.asdict())
  ```
</CodeGroup>

After creating features and schemas, you can add them to ontologies. To learn how to upsert features into an ontology, see [Ontology](/reference/ontology#create-ontology-from-new-features).

## Set a`UIMode` for a feature

You can set a `UIMode` for your classification, which works similarly like switching the `dropdown` toggle inside the platform. The `UIMode` has the following two options:

1. `Classification.UIMode.SEARCHABLE` allows the feature to be searched inside a dropdown menu, equivalent to enabling the dropdown toggle.
2. `Classification.UIMode.HOTKEY` gives each answer option a dedicated hotkey, equivalent to disabling the dropdown toggle.

<CodeGroup>
  ```python Python theme={null}
  radio_classification = Classification(class_type=Classification.Type.RADIO,
                                        name="dog_breed",
                                        options=[Option("poodle")],
                                        required=True,
                                        ui_mode=Classification.UIMode.SEARCHABLE)

  checklist_classification = Classification(class_type=Classification.Type.CHECKLIST,
                                          name="background",
                                          options=[Option("at_park"), Option("has_leash")]
                                          ui_mode=Classification.UIMode.HOTKEY)
  ```
</CodeGroup>

## Set a  `likert scale` for a feature

You can set the parameter `is_likert_scale` for your radio classification if all option values are integers.

```python theme={null}
classification_features = [
    Classification(
        class_type=lb.Classification.Type.RADIO,
        name="Quality Issues",
        options=[
            Option(value="1", label="Blurry"),
            Option(value="2", label="Distorted"),
            Option(value="3", label="OutOfFocus"),
        ],
        required=True,
        is_likert_scale=True,
    )
]
```

## Get a feature

You can get the feature schema by name or schema id. Only top-level feature schemas are supported.

<CodeGroup>
  ```python Python theme={null}
  from labelbox import client

  client = Client(api_key="<YOUR_API_KEY>")

  ## 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. You can get this from the UI
  regulatory_sign_feature_schema = client.get_feature_schema("FEATURE_SCHEMA_ID")

  print(regulatory_sign_feature_schema)
  print(classification_feature)
  ```
</CodeGroup>

## Update feature schema name

Updates the title/name of a feature schema. Only top-level feature schemas are supported.

<CodeGroup>
  ```python Python theme={null}
  client.update_feature_schema_title("<feature_id>", "New Title")
  ```
</CodeGroup>

## Delete or archive a feature in an ontology

Deletes or archives a feature schema from an ontology. If the feature schema is a root-level node with associated labels, it will be *archived*. If the feature schema is a nested node in the ontology without associated labels, it will be deleted. If the feature schema is a nested ontology node with associated labels, it will neither be deleted nor archived.

To *archive* a feature means you can unarchive it later on and retrieve annotations made with this feature. If you delete a feature, the feature and its associated annotations cannot be recovered.

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

## Unarchive a feature in an ontology

Unarchives a feature schema node in an ontology. Only root-level feature schema nodes can be unarchived.

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

## Check whether a feature is archived

Returns `True` if a feature schema is archived in the specified ontology, returns `False` otherwise.

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

  # True or False
  print(result)
  ```
</CodeGroup>
