Training Operations#

This notebook demonstrates how to manage training events using the NVIDIA Air SDK.

Training events enable instructors to create scheduled training sessions with NGC user groups and dedicated simulation environments for attendees.

Setup#

Initialize the API client

[ ]:
from datetime import datetime, timedelta, timezone

from air_sdk import AirApi
from air_sdk.endpoints import Training

# For now we have to use device login for training endpoint
# This is NGC restriction for now
api = AirApi.with_device_login(email='user@example.com', org_num='your-org-num')

Create a Training Event#

Create a new training event with:

  • NGC external user group

  • Template simulation that will be cloned

  • Attendee list

  • Timing configuration for workbench lifecycle

Note: The parent simulation will transition to INACTIVE state after cloning completes. A dedicated training_simulation will be created for the training session.

[ ]:
# First, get a simulation to use as the template
simulation_id = '...'  # Replace with actual simulation ID
template_sim = api.simulations.get(simulation_id)

# Create training event
event_time = datetime.now(timezone.utc) + timedelta(days=7)
training: Training = api.trainings.create(
    name='network-training-101',
    parent_simulation=template_sim.id,
    attendees=['student1@example.com', 'student2@example.com'],
    event_time=event_time,
    sim_start_time=event_time - timedelta(hours=5),
    sim_end_time=event_time + timedelta(days=1),
)

print(f'Created training: {training.name}')
print(f'NGC Group ID: {training.ngc_group_id}')
print(f'Attendees: {len(training.attendees)}')
training.dict()

List Training Events#

List all training events visible to your account. Supports filtering and pagination.

[ ]:
# List all trainings
for training in api.trainings.list():
    print(f'{training.name}: {training.id}')

# Filter by name
filtered = list(api.trainings.list(name='network-training-101'))

# Filter by workbenches status
active_trainings = list(api.trainings.list(workbenches_created=True))

# Search across multiple fields
search_results = list(api.trainings.list(search='network'))

Get Training Details#

Retrieve a specific training event by ID

[ ]:
training_id = '...'  # Replace with actual training ID
training: Training = api.trainings.get(training_id)

print(f'Training: {training.name}')
print(f'Event time: {training.event_time}')
print(f'Template simulation: {training.training_simulation_name}')
print(f'State: {training.training_simulation_state}')
print(f'Workbenches created: {training.workbenches_created}')

# Access the template simulation object (lazy loaded)
template_sim_name = training.training_simulation.name
print(f'Template simulation (via FK): {template_sim_name}')

Update Training Fields#

Update training event details. Only event_time, sim_start_time, and sim_end_time can be updated 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

Note: The name field cannot be updated after creation.

[ ]:
# Update timing fields
new_event_time = datetime.now(timezone.utc) + timedelta(days=10)
training.update(
    event_time=new_event_time,
    sim_start_time=new_event_time - timedelta(hours=5),  # 5h before event
    sim_end_time=new_event_time + timedelta(days=1),  # 1 day after event
)

print(f'Updated event time: {training.event_time}')
print(f'Updated sim_start_time: {training.sim_start_time}')
print(f'Updated sim_end_time: {training.sim_end_time}')

# Or update via API method
updated = api.trainings.update(
    training=training.id,
    event_time=new_event_time,
    sim_start_time=new_event_time - timedelta(hours=5),
    sim_end_time=new_event_time + timedelta(days=1),
)

Manage Attendees#

Add or remove attendees from a training event

[ ]:
# Add attendees via instance method
training.add_attendees(attendees=['student3@example.com', 'student4@example.com'])
print(f'Total attendees: {len(training.attendees)}')

# Remove attendees
training.remove_attendees(attendees=['student1@example.com'])
print(f'Remaining attendees: {len(training.attendees)}')

# Or use API-level methods
api.trainings.add_attendees(training=training.id, attendees=['student5@example.com'])
api.trainings.remove_attendees(training=training.id, attendees=['student2@example.com'])

Get NGC External User Group Information#

Retrieve full details about the training’s NGC external user group, including confirmed users and pending invitations.

Note: This makes an external API call to NGC and requires AIR_INSTRUCTOR, AIR_ORG_ADMIN, or USER_ADMIN roles.

[ ]:
# Get NGC group info via instance method
group_data = training.get_external_user_group()

print(f'Group Name: {group_data["name"]}')
print(f'Organization: {group_data["orgName"]}')
print(f'Resource Group: {group_data["resourceGroup"]}')
print(f'Confirmed Users: {len(group_data.get("confirmedUsers", []))}')
print(f'Pending Invitations: {len(group_data.get("pendingInvitations", []))}')

# Or use API-level method
group_data = api.trainings.get_external_user_group(training=training.id)

Delete a Training Event#

Delete a training event and its associated NGC user group

[ ]:
# Delete via instance method
training.delete()
print('Training deleted successfully')

# Or delete via API method
api.trainings.delete('training-id-123')