> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/dsx-air/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/dsx-air/_mcp/server.

# air_sdk.endpoints.trainings

## Classes

| Name                                                                         | Description                                                                        |
| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| [`TrainingNGCData`](#air_sdkendpointstrainingstrainingngcdata)               | External user group data from NGC for a training event.                            |
| [`TrainingAttendeeDetail`](#air_sdkendpointstrainingstrainingattendeedetail) | Per-attendee onboarding and access status for a training attendee.                 |
| [`Training`](#air_sdkendpointstrainingstraining)                             | Training model representing a training event with NGC group and cloned simulation. |
| [`TrainingEndpointAPI`](#air_sdkendpointstrainingstrainingendpointapi)       | Endpoint API for managing training events.                                         |

## Module Contents

```python
class air_sdk.endpoints.trainings.TrainingNGCData
```

**Bases**: `typing.TypedDict`

External user group data from NGC for a training event.

This data is retrieved from the NGC API and includes information about
the user group, its members, and invitation status.

```python
userGroupId: str
```

```python
orgName: str
```

```python
resourceGroup: str
```

```python
name: str
```

```python
description: str
```

```python
idpListLocked: bool
```

```python
requireMatchingEmail: bool
```

```python
isUserGroupAdmin: bool
```

```python
serviceRoles: list[str]
```

```python
companyName: str
```

```python
groupContactEmail: str
```

```python
permissionSetDesc: str
```

```python
startDate: str
```

```python
endDate: str
```

```python
confirmedUsers: list[str]
```

```python
pendingInvitations: list[str]
```

```python
type: str
```

```python
class air_sdk.endpoints.trainings.TrainingAttendeeDetail
```

**Bases**: `typing.TypedDict`

Per-attendee onboarding and access status for a training attendee.

**Args:**

email: Attendee email address.
has\_onboarded\_in\_air: Whether the attendee has onboarded in DSX Air.
action\_needed: Follow-up action required for access, if any.

**Returns:**

One typed attendee-status entry.

**Example:**

```python
>>> detail: TrainingAttendeeDetail = {
...     'email': 'student@example.com',
...     'has_onboarded_in_air': False,
...     'action_needed': 'User needs to log into DSX Air.',
... }
```

```python
email: str
```

```python
has_onboarded_in_air: bool
```

```python
action_needed: str | None
```

```python
class air_sdk.endpoints.trainings.Training
```

**Bases**: `air_sdk.air_model.AirModel`

Training model representing a training event with NGC group and cloned simulation.

Timing Constraints:

* event\_time must be at least 5h in the future
* sim\_start\_time must be at least 1h in the future and 4h before event\_time
* sim\_end\_time must be at least 24h after event\_time

Update Restrictions:
Only event\_time, sim\_start\_time, and sim\_end\_time can be updated.
Name, parent simulation, checkpoint, and attendees cannot be
modified after creation.

The training\_simulation field is a lazy-loaded foreign key. Accessing it will
automatically fetch the full Simulation object from the API.

```python
get_model_api() -> type[TrainingEndpointAPI]
```

```python
id: str
```

Unique identifier for the training event

```python
name: str
```

Name of the training event (also NGC user group name, must be kebab-case)

```python
display_name: str
```

Human-readable display name for the training event

```python
created: datetime.datetime
```

Timestamp when the training was created

```python
modified: datetime.datetime
```

Timestamp when the training was last modified

```python
creator: str
```

Email of the client that created the training

```python
org: str
```

Organization UUID associated with this training

```python
training_simulation: Simulation
```

Foreign key to template simulation (lazy loaded)

```python
training_simulation_name: str
```

Name of the training simulation (read-only)

```python
training_simulation_state: str
```

State of the training simulation (read-only)

```python
event_time: datetime.datetime
```

When the training event will occur (must be 5h+ in future)

```python
ngc_group_id: str
```

NGC external user group ID (must be kebab-case)

```python
sim_start_time: datetime.datetime
```

When workbenches are created/started
(1h+ future, 4h before event\_time)

```python
sim_end_time: datetime.datetime
```

When workbenches expire/destroyed (24h+ after event\_time)

```python
attendees: list[str]
```

List of validated attendee email addresses

```python
attendee_details: list[TrainingAttendeeDetail]
```

Per-attendee onboarding/access status (read-only)

```python
workbenches_created: bool
```

Whether workbenches have been created

```python
update(
    *,
    display_name: str = ...,
    event_time: datetime.datetime = ...,
    sim_start_time: datetime.datetime = ...,
    sim_end_time: datetime.datetime = ...,
    **kwargs: Any
) -> None
```

Update individual fields of the training event.

Only display\_name, event\_time, sim\_start\_time, and sim\_end\_time can be
updated. Name, parent simulation, checkpoint, and attendees cannot be
modified via this endpoint after creation.

Timing Constraints:

* event\_time: Must be at least 5h in the future
* sim\_start\_time: Must be 1h+ in future and 4h before event\_time
* sim\_end\_time: Must be at least 24h after event\_time

**Parameters:**

* `display_name` – Human-readable display name for the training event
* `event_time` – When the training event will occur
* `sim_start_time` – When workbenches are created/started
* `sim_end_time` – When workbenches expire/destroyed
* `**kwargs` – Additional fields for future API compatibility

**Raises:**

* `ValidationError` – If timing constraints are violated

**Example:**

```python
>>> training.update(
...     event_time=datetime(2026, 3, 15, 9, 0),
...     sim_start_time=datetime(2026, 3, 15, 5, 0),
...     sim_end_time=datetime(2026, 3, 16, 9, 0)
... )
```

```python
add_attendees(
    *,
    attendees: list[str],
    **kwargs: Any
) -> None
```

Add attendees to the training event.

**Parameters:**

* `attendees` – List of email addresses to add as attendees
* `**kwargs` – Additional parameters

**Example:**

```python
>>> training.add_attendees(
...     attendees=['user1@example.com', 'user2@example.com']
... )
```

```python
remove_attendees(
    *,
    attendees: list[str],
    **kwargs: Any
) -> None
```

Remove attendees from the training event.

**Parameters:**

* `attendees` – List of email addresses to remove from attendees
* `**kwargs` – Additional parameters

**Example:**

```python
>>> training.remove_attendees(
...     attendees=['user1@example.com']
... )
```

```python
get_external_user_group(**kwargs: Any) -> TrainingNGCData
```

Get NGC external user group information.

Makes an external API call to NGC to retrieve full details about the
training's user group, including confirmed users and pending invitations.

**Parameters:**

* `**kwargs` – Additional parameters

**Returns:**

NGC user group data including members and invitation status

**Example:**

```python
>>> group_data = training.get_external_user_group()
>>> print(f'Group: {group_data["name"]}')
>>> print(f'Confirmed users: {group_data.get("confirmedUsers", [])}')
>>> print(f'Pending invitations: {group_data.get("pendingInvitations", [])}')
```

```python
get_workbenches(
    *,
    id: str = ...,
    creator: str = ...,
    assigned_to: str = ...,
    **kwargs: Any
) -> IndexableIterator[Simulation]
```

Get the workbench simulations for this training.

The training's `training_simulation` (the template) is automatically
excluded from the results; only attendee workbenches are returned.
Results are also scoped to simulations the calling user has permission
to read.

**Parameters:**

* `id` – Filter by the workbench simulation ID
* `creator` – Filter by the username of the simulation creator
* `assigned_to` – Filter by the email of the user assigned to the workbench simulation. This will match `creator` unless the assignee has never logged into DSX Air before.
* `**kwargs` – Additional filter parameters

**Returns:**

Iterator of workbench `Simulation` instances for this training

**Example:**

```python
>>> # All workbenches for the training
>>> for sim in training.get_workbenches():
...     print(sim.name)
>>> # Find the workbench assigned to a specific attendee
>>> sims = list(training.get_workbenches(
...     assigned_to='student@example.com'
... ))
```

```python
class air_sdk.endpoints.trainings.TrainingEndpointAPI
```

**Bases**: `air_sdk.air_model.BaseEndpointAPI[air_sdk.endpoints.trainings.Training]`

Endpoint API for managing training events.

Provides methods for listing, creating, retrieving, updating, and deleting
training events, as well as managing attendees and retrieving NGC user group
information.

```python
API_PATH: str
```

```python
ATTENDEES_ADD_PATH: str
```

```python
ATTENDEES_REMOVE_PATH: str
```

```python
EXTERNAL_USER_GROUP_PATH: str
```

```python
WORKBENCH_SIMULATIONS_PATH: str
```

```python
model: type[Training]
```

```python
list(
    *,
    display_name: str = ...,
    limit: int = ...,
    name: str = ...,
    ngc_group_id: str = ...,
    offset: int = ...,
    ordering: str = ...,
    search: str = ...,
    training_simulation: str | PrimaryKey = ...,
    workbenches_created: bool = ...,
    **params: Any
) -> Iterator[Training]
```

List all training events.

**Parameters:**

* `display_name` – Filter by training display name
* `limit` – Number of results to return per page
* `name` – Filter by training name
* `ngc_group_id` – Filter by NGC external user group ID
* `offset` – Initial index from which to return results
* `ordering` – Order by field (prefix with "-" for desc). Options: -created, -creator, -display\_name, -event\_time, -modified, -name, -ngc\_group\_id, -sim\_end\_time, -sim\_start\_time, -training\_simulation\_name, -training\_simulation\_state, -workbenches\_created, created, creator, display\_name, event\_time, modified, name, ngc\_group\_id, sim\_end\_time, sim\_start\_time, training\_simulation\_name, training\_simulation\_state, workbenches\_created
* `search` – Search by name, display\_name, creator, training\_simulation\_name, training\_simulation\_state, event\_time, sim\_start\_time, sim\_end\_time, created
* `training_simulation` – Filter by template simulation ID
* `workbenches_created` – Filter by workbenches creation status
* `**params` – Additional filter parameters

**Returns:**

Iterator of Training instances

**Example:**

```python
>>> for training in api.trainings.list():
...     print(training.name)
>>> # Filter by name
>>> trainings = api.trainings.list(name='network-training')
>>> # Filter by simulation
>>> trainings = api.trainings.list(training_simulation='sim-123')
```

```python
create(
    *,
    name: str,
    parent_simulation: str | PrimaryKey,
    attendees: list[str],
    event_time: datetime.datetime,
    sim_start_time: datetime.datetime,
    sim_end_time: datetime.datetime,
    display_name: str = ...,
    parent_simulation_checkpoint: str | PrimaryKey = ...,
    **kwargs: Any
) -> Training
```

Create a new training event with NGC group and cloned simulation.

The simulation will be cloned when creating the training. After cloning
completes, the parent\_simulation transitions to INACTIVE state and is no
longer associated with the training. A dedicated training\_simulation is
created for the training session.

**Parameters:**

* `name` – Name of the training event (must be kebab-case, used as NGC user group name)
* `parent_simulation` – Simulation to clone for the training (transitions to INACTIVE after cloning)
* `attendees` – List of attendee email addresses (required, case-sensitive, no duplicates)
* `event_time` – When the training event will occur (must be 5h+ in future, sim\_end\_time must be 24h+ after this)
* `sim_start_time` – When workbenches are created/started (must be 1h+ in future and 4h before event\_time)
* `sim_end_time` – When workbenches expire/destroyed (must be 24h+ after event\_time)
* `display_name` – Human-readable display name for the training event (defaults to `name` if not provided)
* `parent_simulation_checkpoint` – Checkpoint from parent\_simulation to clone onto training\_simulation (optional)
* `**kwargs` – Additional fields for future API compatibility

**Returns:**

Created Training instance

**Example:**

```python
>>> training = api.trainings.create(
...     name='network-training-101',
...     parent_simulation='sim-id-123',
...     attendees=['student1@example.com', 'student2@example.com'],
...     event_time=datetime(2026, 3, 15, 9, 0),
...     sim_start_time=datetime(2026, 3, 15, 5, 0),
...     sim_end_time=datetime(2026, 3, 16, 9, 0)
... )
```

```python
get(
    pk: PrimaryKey,
    **params: Any
) -> Training
```

Retrieve a specific training event.

**Parameters:**

* `pk` – Training ID
* `**params` – Additional query parameters

**Returns:**

Training instance

**Example:**

```python
>>> training = api.trainings.get('training-id-123')
>>> print(training.name)
```

```python
patch(
    pk: PrimaryKey,
    *,
    display_name: str = ...,
    event_time: datetime.datetime = ...,
    sim_start_time: datetime.datetime = ...,
    sim_end_time: datetime.datetime = ...,
    **kwargs: Any
) -> Training
```

Update individual fields of a training event.

Only display\_name, event\_time, sim\_start\_time, and sim\_end\_time can be
updated.

**Parameters:**

* `pk` – Training ID
* `display_name` – Human-readable display name for the training event
* `event_time` – When the training event will occur
* `sim_start_time` – When workbenches are created/started
* `sim_end_time` – When workbenches expire/destroyed
* `**kwargs` – Additional fields for future API compatibility

**Returns:**

Updated Training instance

**Example:**

```python
>>> training = api.trainings.patch(
...     'training-id-123',
...     event_time=datetime(2026, 3, 15, 9, 0),
... )
```

```python
delete(
    pk: PrimaryKey,
    **kwargs: Any
) -> None
```

Delete a training event and its associated NGC user group.

**Parameters:**

* `pk` – Training ID
* `**kwargs` – Additional parameters

**Example:**

```python
>>> api.trainings.delete('training-id-123')
```

```python
update(
    *,
    training: Training | PrimaryKey,
    display_name: str = ...,
    event_time: datetime.datetime = ...,
    sim_start_time: datetime.datetime = ...,
    sim_end_time: datetime.datetime = ...,
    **kwargs: Any
) -> Training
```

Update individual fields of a training event.

Only display\_name, event\_time, sim\_start\_time, and sim\_end\_time can be
updated. Name, parent simulation, checkpoint, and attendees cannot be
modified after creation.

Timing Constraints:

* event\_time: Must be at least 5h in the future
* sim\_start\_time: Must be 1h+ in future and 4h before event\_time
* sim\_end\_time: Must be at least 24h after event\_time

**Parameters:**

* `training` – Training instance or training ID
* `display_name` – Human-readable display name for the training event
* `event_time` – When the training event will occur
* `sim_start_time` – When workbenches are created/started
* `sim_end_time` – When workbenches expire/destroyed
* `**kwargs` – Additional fields for future API compatibility

**Returns:**

Updated Training instance

**Raises:**

* `ValidationError` – If timing constraints are violated

**Example:**

```python
>>> training = api.trainings.get('training-id-123')
>>> api.trainings.update(
...     training=training,
...     event_time=datetime(2026, 3, 15, 9, 0),
...     sim_start_time=datetime(2026, 3, 15, 5, 0)
... )
```

```python
add_attendees(
    *,
    training: Training | PrimaryKey,
    attendees: list[str],
    **kwargs: Any
) -> None
```

Add attendees to an existing training event.

**Parameters:**

* `training` – Training instance or training ID
* `attendees` – List of email addresses to add
* `**kwargs` – Additional parameters

**Example:**

```python
>>> api.trainings.add_attendees(
...     training='training-id-123', attendees=['newuser@example.com']
... )
```

```python
remove_attendees(
    *,
    training: Training | PrimaryKey,
    attendees: list[str],
    **kwargs: Any
) -> None
```

Remove attendees from an existing training event.

**Parameters:**

* `training` – Training instance or training ID
* `attendees` – List of email addresses to remove
* `**kwargs` – Additional parameters

**Example:**

```python
>>> api.trainings.remove_attendees(  # fmt: skip
...     training='training-id-123', attendees=['user@example.com']
... )
```

```python
get_external_user_group(
    *,
    training: Training | PrimaryKey,
    **kwargs: Any
) -> TrainingNGCData
```

Get NGC external user group data for a training.

Makes an external API call to NGC to retrieve full details about the
training's user group, including confirmed users and pending invitations.

Requires AIR\_INSTRUCTOR, AIR\_ORG\_ADMIN, or USER\_ADMIN roles.

**Parameters:**

* `training` – Training instance or ID
* `**kwargs` – Additional parameters

**Returns:**

NGC user group data including members and invitation status

**Example:**

```python
>>> group_data = api.trainings.get_external_user_group(
...     training='training-id-123'
... )
>>> print(f"Group name: {group_data['name']}")
>>> print(f"Organization: {group_data['orgName']}")
>>> confirmed = group_data.get('confirmedUsers', [])
>>> pending = group_data.get('pendingInvitations', [])
>>> print(f"Total users: {len(confirmed)} confirmed, {len(pending)} pending")
```

```python
list_workbenches(
    *,
    training: Training | PrimaryKey,
    id: str = ...,
    creator: str = ...,
    assigned_to: str = ...,
    limit: int = ...,
    offset: int = ...,
    **kwargs: Any
) -> IndexableIterator[Simulation]
```

List workbench simulations associated with a training event.

Useful for instructors who need to find all attendee workbenches for a
given training session. The training's `training_simulation` (the
template) is automatically excluded from the results; only attendee
workbenches are returned. Results are also scoped to simulations the
calling user has permission to read.

**Parameters:**

* `training` – Training instance or training ID
* `id` – Filter by the workbench simulation ID
* `creator` – Filter by the username of the simulation creator
* `assigned_to` – Filter by the email of the user assigned to the workbench simulation. This will match `creator` unless the assignee has never logged into DSX Air before.
* `limit` – Number of results to return per page
* `offset` – Initial index from which to return results
* `**kwargs` – Additional filter parameters

**Returns:**

Iterator of workbench `Simulation` instances for the training

**Example:**

```python
>>> # All workbenches for a training
>>> for sim in api.trainings.list_workbenches(training='training-id-123'):
...     print(sim.name)
>>> # Find the workbench assigned to a specific attendee
>>> sims = list(api.trainings.list_workbenches(
...     training='training-id-123',
...     assigned_to='student@example.com',
... ))
```