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

# TypedDict in Python

> Define and type structured dictionaries, optional keys, union types, and LangGraph state using TypedDict.

## 1. What is TypedDict?

`TypedDict` defines the expected **structure of a dictionary** using type hints.

```python theme={null}
from typing import TypedDict

class Student(TypedDict):
    name: str
    age: int
    marks: float
```

It is still a normal Python dictionary:

```python theme={null}
student: Student = {
    "name": "Ravi",
    "age": 21,
    "marks": 85.5
}
```

`TypedDict` is mainly for **static type checking**. It does not perform runtime validation.

### Practice

**Define a `Movie` `TypedDict` with fields `title` (str), `year` (int), and `rating` (float). Create a valid instance of it.**

<Accordion title="Solution">
  ```python theme={null}
  from typing import TypedDict

  class Movie(TypedDict):
      title: str
      year: int
      rating: float

  movie: Movie = {
      "title": "Inception",
      "year": 2010,
      "rating": 8.8
  }
  ```
</Accordion>

***

## 2. Required Keys

By default, all keys are required.

```python theme={null}
class Student(TypedDict):
    name: str
    age: int
```

```python theme={null}
student = {
    "name": "Ravi",
    "age": 21
}
```

### Practice

**Define a `Product` `TypedDict` with fields `name` (str) and `price` (float). Create an instance that misses a required key and note what a static type checker would report.**

<Accordion title="Solution">
  ```python theme={null}
  from typing import TypedDict

  class Product(TypedDict):
      name: str
      price: float

  # This is invalid because 'price' is missing:
  # type checkers like mypy will raise an error.
  invalid_product: Product = {
      "name": "Laptop"
  }
  ```
</Accordion>

***

## 3. Union Types with `|`

Modern Python supports `|` for union types.

```python theme={null}
class Student(TypedDict):
    name: str
    age: int | None
```

`age` is **required**, but its value can be `int` or `None`.

```python theme={null}
{"name": "Ravi", "age": 21}     # valid
{"name": "Ravi", "age": None}   # valid
{"name": "Ravi"}                # not valid
```

### Important

```text theme={null}
int | None
    → controls the allowed VALUE

NotRequired[int]
    → controls whether the KEY can be omitted
```

### Practice

**Define a `User` `TypedDict` where `email` is `str | None`. Create an instance with `email` as `None` and another with a string email.**

<Accordion title="Solution">
  ```python theme={null}
  from typing import TypedDict

  class User(TypedDict):
      username: str
      email: str | None

  # Both are valid, but email must be present
  user1: User = {
      "username": "alice",
      "email": None
  }

  user2: User = {
      "username": "bob",
      "email": "bob@example.com"
  }
  ```
</Accordion>

***

## 4. Optional Keys with `NotRequired`

Use `NotRequired` when the key itself can be omitted.

```python theme={null}
from typing import TypedDict, NotRequired

class Student(TypedDict):
    name: str
    age: NotRequired[int]
```

Both are valid:

```python theme={null}
{"name": "Ravi", "age": 21}
{"name": "Ravi"}
```

To make the key optional **and** allow `None`:

```python theme={null}
class Student(TypedDict):
    age: NotRequired[int | None]
```

Now all are valid:

```python theme={null}
{"age": 21}
{"age": None}
{}
```

### Practice

**Define a `Book` `TypedDict` where `title` (str) and `author` (str) are required, but `pages` (int) and `genre` (str | None) are `NotRequired`. Create an instance without `pages` and `genre`, and another with both.**

<Accordion title="Solution">
  ```python theme={null}
  from typing import TypedDict, NotRequired

  class Book(TypedDict):
      title: str
      author: str
      pages: NotRequired[int]
      genre: NotRequired[str | None]

  # Valid: Pages and genre omitted
  book1: Book = {
      "title": "1984",
      "author": "George Orwell"
  }

  # Valid: Pages and genre provided
  book2: Book = {
      "title": "To Kill a Mockingbird",
      "author": "Harper Lee",
      "pages": 281,
      "genre": None
  }
  ```
</Accordion>

***

## 5. TypedDict vs Pydantic

| TypedDict                      | Pydantic                       |
| ------------------------------ | ------------------------------ |
| Describes dictionary structure | Defines a data model           |
| Mainly for type checking       | Runtime validation             |
| Object remains a `dict`        | Object is a model              |
| Common for internal state      | Common for API/data validation |

Simple rule:

```text theme={null}
TypedDict → What should the dictionary look like?

Pydantic → Is the data valid?
```

***

## 6. TypedDict in LangGraph

`TypedDict` is commonly used to define **LangGraph state**.

```python theme={null}
from typing import TypedDict, NotRequired

class AgentState(TypedDict):
    question: str
    context: NotRequired[str]
    answer: NotRequired[str]
```

Initially:

```python theme={null}
state = {
    "question": "What is RAG?"
}
```

After retrieval:

```python theme={null}
state = {
    "question": "What is RAG?",
    "context": "RAG retrieves relevant information..."
}
```

After generation:

```python theme={null}
state = {
    "question": "What is RAG?",
    "context": "RAG retrieves relevant information...",
    "answer": "RAG combines retrieval with generation."
}
```

This makes `TypedDict` particularly useful for **state that evolves as it moves between LangGraph nodes**.

### Practice

**Define an `LLMState` `TypedDict` for a translation agent with required key `original_text` (str), and optional keys `source_language` (NotRequired\[str]), `target_language` (NotRequired\[str]), and `translated_text` (NotRequired\[str]). Create instances representing the state at different stages.**

<Accordion title="Solution">
  ```python theme={null}
  from typing import TypedDict, NotRequired

  class LLMState(TypedDict):
      original_text: str
      source_language: NotRequired[str]
      target_language: NotRequired[str]
      translated_text: NotRequired[str]

  # Stage 1: Initial state
  state1: LLMState = {
      "original_text": "Bonjour tout le monde"
  }

  # Stage 2: Languages detected/defined
  state2: LLMState = {
      "original_text": "Bonjour tout le monde",
      "source_language": "French",
      "target_language": "English"
  }

  # Stage 3: Translated text populated
  state3: LLMState = {
      "original_text": "Bonjour tout le monde",
      "source_language": "French",
      "target_language": "English",
      "translated_text": "Hello everyone"
  }
  ```
</Accordion>

***

## 7. Quick Reference

```text theme={null}
TypedDict
    → defines dictionary structure

int | None
    → value can be int or None
    → key is still required

NotRequired[int]
    → key can be omitted
    → if present, value must be int

NotRequired[int | None]
    → key can be omitted
    → if present, value can be int or None
```

## 8. Key Takeaway

```text theme={null}
TypedDict = structure of a dictionary

Pydantic = validation of structured data

For LangGraph:
TypedDict → commonly used to define graph state
```

***

## Practice & Exercises

To reinforce what you've learned in this section (defining TypedDicts, required vs optional keys, union types, and graph states), practice with these interactive notebooks:

<CardGroup cols={2}>
  <Card title="Follow-Along Practice" icon="laptop-code">
    Practice defining dictionary structures, working with Required and NotRequired keys, using modern Union types, and modeling LangGraph states.

    [💻 VS Code](vscode://file/Users/sivaprasad/Downloads/GenAI%20With%20Python/public/notebooks/basics_exercises/Typed_Dict_Practice.ipynb) | [🚀 Colab](https://colab.research.google.com/github/prasad230776/genai-course/blob/master/public/notebooks/basics_exercises/Typed_Dict_Practice.ipynb) | <a href="/public/notebooks/basics_exercises/Typed_Dict_Practice.ipynb" download>📥 Download</a>
  </Card>

  <Card title="Practice Exercises" icon="pen-to-square">
    Test your knowledge by building schemas for Movies, Products, Users, Books, and translation LLMStates with proper type hinting.

    [💻 VS Code](vscode://file/Users/sivaprasad/Downloads/GenAI%20With%20Python/public/notebooks/basics_exercises/Typed_Dict_Exercises.ipynb) | [🚀 Colab](https://colab.research.google.com/github/prasad230776/genai-course/blob/master/public/notebooks/basics_exercises/Typed_Dict_Exercises.ipynb) | <a href="/public/notebooks/basics_exercises/Typed_Dict_Exercises.ipynb" download>📥 Download</a>
  </Card>
</CardGroup>
