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

# Import and Export Functionality

```python
# Imports (run once)
import json

from air_sdk import AirApi, InstructionExportChoice, SimState
from air_sdk.endpoints import Simulation
```

```python
# Authentication (run once)
api = AirApi.with_ngc_config()
# OR api = AirApi.with_api_key(api_key="...")
# OR api = AirApi.with_device_login(email="...", org_num="...")
#    ^ use in terminal only — not supported in Jupyter notebooks
```

## Import

### Import a Simulation from a JSON Simulation Manifest File

```python
file_path = '../files/exports/export_without_oob.json'
sim: Simulation = api.simulations.import_from_simulation_manifest(
    simulation_manifest=file_path
)

print(f'Current state of simulation: {sim.state}')
print('waiting for simulation to finish importing...', end='')
sim.wait_for_state(SimState.INACTIVE, error_states=SimState.INVALID)
print(f'Current state of simulation: {sim.state}')
```

```
Current state of simulation: IMPORTING
waiting for simulation to finish importing....
Current state of simulation: INACTIVE
```

### Import from Data

```python
ztp_script_path = '../files/ztp/basic_script.sh'
with open(ztp_script_path, 'r') as f:
    ztp_script = f.read()

json_data = {
    'format': 'JSON',
    'name': 'JSON Sim',
    'content': {
        'nodes': {
            'node1': {
                'cpu': 2,
                'memory': 1024,
                'storage': 10,
                'os': 'generic/ubuntu2204',
                'cpu_arch': 'x86',
            },
        },
        'oob': False,
    },
    'ztp': ztp_script,
}

sim: Simulation = api.simulations.import_from_data(**json_data)

print(f'Current state of simulation: {sim.state}')
print('waiting for simulation to finish importing...')
sim.wait_for_state(SimState.INACTIVE, error_states=SimState.INVALID)
print(f'Current state of simulation: {sim.state}')
```

```
Current state of simulation: IMPORTING
waiting for simulation to finish importing....
Current state of simulation: INACTIVE
```

### Import a Topology That Declares Services and Instructions

A JSON topology may declare top-level `services` (exposed ports) and
`instructions` (setup commands run on nodes) lists, alongside `nodes` and
`links`. They are top-level (rather than nested under a node) so that the
`oob-mgmt-server` can be targeted too. When present, they are imported with the
simulation.

```python
topology_with_extras = {
    'format': 'JSON',
    'name': 'Sim with Services and Instructions',
    'content': {
        'nodes': {
            'server1': {
                'cpu': 2,
                'memory': 1024,
                'storage': 10,
                'os': 'generic/ubuntu2204',
                'cpu_arch': 'x86',
            },
        },
        'oob': False,
        # Top-level services: exposed ports on a node's interface.
        'services': [
            {
                'name': 'SSH',
                'service_type': 'SSH',
                'node': 'server1',
                'interface': 'eth0',
                'port': 22,
            },
        ],
        # Top-level instructions: setup commands run on nodes.
        'instructions': [
            {
                'node': 'server1',
                'executor': 'shell',
                'data': 'echo "hello from server1"',
            },
        ],
    },
}

sim: Simulation = api.simulations.import_from_data(**topology_with_extras)

print(f'Current state of simulation: {sim.state}')
print('waiting for simulation to finish importing...')
sim.wait_for_state(SimState.INACTIVE, error_states=SimState.INVALID)
print(f'Current state of simulation: {sim.state}')
```

## Export

### Export an Existing Simulation

```python
sim_id = '...'  # Replace with your simulation ID
sim: Simulation = api.simulations.get(sim_id)

export_data = sim.export()

with open('my_export.json', 'w') as f:
    json.dump(export_data, f)
```

### Export including Instructions and Services

By default an export omits instructions and services. Opt in with
`include_instructions` (an `InstructionExportChoice` — `NONE`, `REPEATABLE`, or
`REPEATABLE_OR_NOT_READY`) and `include_services=True`. The exported topology
then carries top-level `services` and `instructions` lists, so it round-trips
back through `import_from_data` / `import_from_simulation_manifest`.

```python
sim_id = '...'  # Replace with your simulation ID
sim: Simulation = api.simulations.get(sim_id)

export_data = sim.export(
    include_instructions=InstructionExportChoice.REPEATABLE,
    include_services=True,
)

# The export now carries top-level 'services' and 'instructions' lists.
print('services:', export_data['content'].get('services'))
print('instructions:', export_data['content'].get('instructions'))

with open('my_export_with_extras.json', 'w') as f:
    json.dump(export_data, f)
```