# Concepts

## What are Concepts?

**Concepts** define how data flows in and out of a procedure:

* **Input concepts** represent the inputs that a procedure requires.
* **Output concepts** represent the results that a procedure generates.

## Concept Types

Input and output concepts can be defined as either **standard** or **custom** types.

### Standard Types

The following Python data types can be used to define concepts:

<table><thead><tr><th width="154.859375">Category</th><th>Supported Python Data Types</th></tr></thead><tbody><tr><td><strong>Text</strong></td><td><code>str</code></td></tr><tr><td><strong>Number</strong></td><td><code>float</code>, <code>int</code></td></tr><tr><td><strong>Boolean</strong></td><td><code>bool</code></td></tr><tr><td><strong>Bytes</strong></td><td><code>bytes</code></td></tr><tr><td><strong>Date</strong></td><td><code>datetime.datetime</code>, <code>datetime.date</code>, <code>datetime.time</code></td></tr><tr><td><strong>File</strong></td><td><code>typing.IO</code></td></tr><tr><td><strong>UUID</strong></td><td><code>uuid.UUID</code></td></tr><tr><td><strong>Table</strong></td><td><code>pyarrow.Table</code>, <code>arro3.core.Table</code>, <code>nanoarrow.ArrayStream</code></td></tr><tr><td><strong>Lists</strong></td><td><code>List[str]</code>, <code>List[int]</code></td></tr><tr><td><strong>Dictionary</strong></td><td><p><code>Dict[str, Any]</code></p><blockquote><p><em>Note:<code>Any</code>can be any of the other supported types.</em></p></blockquote></td></tr></tbody></table>

### Custom Types

Concepts can also be **custom** types. Custom concepts must be marked with the [**@concept**](https://docs.kognitos.com/legacy/legacy-experience/books/custom-books/api-reference/concepts) decorator. Using a [dataclass](https://docs.python.org/3/library/dataclasses.html) is recommended. For example:

```python
@concept(is_a="office user")
@dataclass
class OfficeUser:
    """
    An Office User represents a user in the Microsoft Graph. It includes key user details such as display name,
    email address, and job title.

    Attributes:
        id: The unique identifier for the user.
        display_name: The name displayed in the address book for the user.
        email_address: The user's email address (usually their user principal name).
        job_title: The user's job title.
    """

    id: str
    display_name: Optional[str] = None
    email_address: Optional[str] = None
    job_title: Optional[str] = None
    ...
```

***

## Concepts vs. Parameters

**Concepts** and **parameters** are two different entities that are closely related.

### Concepts

**Concepts** are operated on by Kognitos procedures. Some concepts are included in the **name** of the [@procedure](#bdk-procedure-decorator) decorator.

### Parameters

**Parameters** are operated on by Python functions. They are defined in a function's signature and are specific to the function's implementation.

#### How Are They Related?

An internal mapping is created between a Python function and a Kognitos procedure. To ensure a correct mapping, concepts and parameters must [**match**](#concept-parameter-matching).

***

## Concept-Parameter Matching

Concepts and parameter names must **match** to ensure they are properly mapped internally.

### Guidelines

Match concepts to parameters by following these guidelines:

1. **Replace spaces with underscores.**
2. **Drop possessive constructions** ('s).
3. **Consider each connected** [**noun phrase**](https://docs.kognitos.com/legacy/legacy-experience/books/custom-books/api-reference/noun-phrases) as a separate parameter. Non-essential noun phrases (e.g., "field," "value") included to clarify context do not require a corresponding parameter.
4. **Don't map articles** ('an', 'a', 'the') to parameters; only the nouns they connect should be considered.
5. **Define optional parameters** in cases where the input concept is not explicitly defined in the procedure name.

### Example 1

In this example, the concept **red car** maps to the parameter `red_car`. The space is replaced with an underscore.

```python
@procedure("to start a red car")
def unique_function_name(self, red_car: type) -> output_type:
```

### Example 2

In the example below:

* **servicenow's ticket** maps to `ticket`
* **field** maps to `field`
* **outlook's standard user** maps to `standard_user`

```python
@procedure("to send a servicenow's ticket's field to an outlook's standard user)
def func(self, ticket: Ticket, field: NounPhrase, standard_user: OutlookUser):
```

### Example 3

In this example, the concept **ticket** maps to the parameter `ticket`. The possessive construct ('s) is dropped and the word "field" is ignored.

```python
@procedure("to update a ticket's field")
def update_field(self, ticket: Ticket, new_value: Any):
```

### Example 4

In the example below, the concept of **priority** is not explicitly stated in the procedure name. It maps to the optional function parameter, `priority`.

```python
@procedure("to assign the task to the user")
def assign_task(self, task: Task, user: User, priority: Optional[str] = None) -> None:
  """Assign a task to a user.

  Input Concepts:
    the task: The action of piece of work that needs to be completed. 
    the user: The user that the action is to be assigned to.
    the priority: The level of importance or urgency of the task.
    
  Example 1:
    Assign the task to the user

    >>> assign the task to the user

  Example 2:
    Assign the task to the user with a priority

    >>> assign the task to the user with
          the priority is "high"
  """
```

### Example 5

In this example:

* **the city** maps to the parameter `city`
* **the unit** maps to the optional parameter `the unit`

The output concept, **current temperature**, is wrapped in parentheses in the procedure name.

```python
@procedure("to get the (current temperature) at a city")
def current_temperature(self, city: NounPhrase, unit: Optional[NounPhrase] = NounPhrase("standard")) -> float:
    """Fetch the current temperature for a specified city.

    Input Concepts:
        the city: The name of the city.
        the unit: Unit of measurement.

    Output Concepts:
        the current temperature: The current temperature in the specified units of measurement, or None if an error occurs.

    Example 1:
        Retrieve the current temperature at London

        >>> get the current temperature at London

    Example 2:
        Retrieve the current temperature at London in Celsius

        >>> get the current temperature at Buenos Aires with
        ...     the unit is metric
    """
```
