System Specifications#
How to Retrieve Queue Information for a Tapis System
by Silvia Mazzoni, DesignSafe, 2025
You can use Tapis to retrieve detailed specifications for any registered system — for example, Stampede3 — using:
t.systems.getSystem(systemId=system_id)
This returns a complete system configuration, including available job queues and their limits.
The utility function:#
Since queue details are especially useful when selecting where to run your job (e.g., based on max runtime, cores per node, or job limits), we’ll use a utility function to extract and format this information.
Retrieves the system’s metadata
Parses the nested dictionary
Converts the queue information into a clean, readable Pandas DataFrame
You can then compare queues and choose the one that best matches your job requirements.
User Input#
system_id = 'stampede3'
Using local utilities library
Connect to Tapis#
t=OpsUtils.connect_tapis()
-- Checking Tapis token --
Token loaded from file. Token is still valid!
Token expires at: 2025-08-22T03:13:01+00:00
Token expires in: 3:52:24.962947
-- LOG IN SUCCESSFUL! --
Get System Info#
system_def = t.systems.getSystem(systemId=system_id)
# this command returns a nested TapisResults object
Pretty-print system_def#
display_tapis_results.py
# ../OpsUtils/OpsUtils/Tapis/display_tapis_results.py
def display_tapis_results(thisAppSchema):
"""
Pretty-print a Tapis App schema (or any nested TapisResult/dict/list) in a
JSON-like format with readable grouping and indentation.
Behavior
--------
- Accepts a TapisResult, dict, or list.
- Groups and prints keys in the order: scalars → lists → nested dicts.
- Handles TapisResult values by flattening their internal __dict__.
- Prints arrays either inline (simple scalars) or expanded (objects).
- Shows a header with app id and version (if present).
Parameters
----------
thisAppSchema : tapipy.tapis.TapisResult | dict | list
The app schema or object to render.
Returns
-------
None
This function prints to stdout. It does not return a value.
Example
-------
# Given a Tapis app schema returned by tapipy:
display_tapis_results(app_schema)
Author
------
Silvia Mazzoni, DesignSafe (silviamazzoni@yahoo.com)
Date
----
2025-08-14
Version
-------
1.0
"""
try:
from tapipy.tapis import TapisResult
except Exception:
class TapisResult: # sentinel so isinstance checks won’t crash if tapipy not available
pass
def _is_simple_scalar(x):
return isinstance(x, (type(None), bool, int, float, str))
def _quote_if_str(x):
return f'"{x}"' if isinstance(x, str) else x
def print_nested(key_prefix, obj, indent=1):
sp = ' ' * indent
# Unwrap TapisResult to dict
if isinstance(obj, TapisResult):
obj = obj.__dict__
# Dict handling
if isinstance(obj, dict):
dict_keys, list_keys, scalar_keys = [], [], []
for k, v in obj.items():
v_unwrap = v.__dict__ if isinstance(v, TapisResult) else v
if isinstance(v_unwrap, dict):
dict_keys.append(k)
elif isinstance(v_unwrap, list):
list_keys.append(k)
else:
scalar_keys.append(k)
# print in order: scalars, lists, dicts
ordered = [*scalar_keys, *list_keys, *dict_keys]
for i, k in enumerate(ordered):
v = obj[k]
v_unwrap = v.__dict__ if isinstance(v, TapisResult) else v
# Nested dict or object
if isinstance(v_unwrap, dict):
# opening brace for top-level objects
if key_prefix:
print(f'{sp}{key_prefix}{k}: ' + '{')
next_prefix = ""
else:
print(f'{sp}{k}: ' + '{')
next_prefix = ""
print_nested(next_prefix, v_unwrap, indent + 1)
print(f'{sp}' + '}')
if i != len(ordered) - 1:
pass # stylistically omit commas for readability
# Lists
elif isinstance(v_unwrap, list):
# Decide inline vs expanded
contains_objects = any(
(isinstance(it, (dict, TapisResult))) for it in v_unwrap
)
label = f'{sp}{key_prefix}{k}: ' if key_prefix else f'{sp}{k}: '
if not v_unwrap:
print(label + '[]')
elif contains_objects:
print(label + '[')
for j, it in enumerate(v_unwrap):
it_unwrap = it.__dict__ if isinstance(it, TapisResult) else it
if isinstance(it_unwrap, dict):
print(' ' * (indent + 1) + '{')
print_nested("", it_unwrap, indent + 2)
print(' ' * (indent + 1) + '}')
else:
val = _quote_if_str(it_unwrap)
print(' ' * (indent + 1) + f'{val}')
if j != len(v_unwrap) - 1:
pass # omit commas for readability
print(sp + ']')
else:
# all simple values → inline
vals = [_quote_if_str(x) for x in v_unwrap]
print(label + f'[{", ".join(map(str, vals))}]')
# Scalars
else:
val = _quote_if_str(v_unwrap)
label = f'{sp}{key_prefix}{k}: ' if key_prefix else f'{sp}{k}: '
print(label + f'{val}')
# List handling (rare for top-level)
elif isinstance(obj, list):
sp = ' ' * indent
if not obj:
print(sp + '[]')
return
contains_objects = any(isinstance(it, (dict, TapisResult)) for it in obj)
if contains_objects:
print(sp + '[')
for it in obj:
it_unwrap = it.__dict__ if isinstance(it, TapisResult) else it
if isinstance(it_unwrap, dict):
print(' ' * (indent + 1) + '{')
print_nested("", it_unwrap, indent + 2)
print(' ' * (indent + 1) + '}')
else:
print(' ' * (indent + 1) + f'{_quote_if_str(it_unwrap)}')
print(sp + ']')
else:
vals = [_quote_if_str(x) for x in obj]
print(sp + f'[{", ".join(map(str, vals))}]')
# Fallback scalar
else:
val = _quote_if_str(obj)
print(sp + f'{val}')
# Header
print('########################################')
print('########################################')
# Body (start with a label to indicate the root)
print('{')
print_nested("", thisAppSchema, indent=1)
print('}')
print('########################################')
OpsUtils.display_tapis_results(system_def)
########################################
########################################
{
isPublic: True
isDynamicEffectiveUser: True
tenant: "designsafe"
id: "stampede3"
description: "System for running jobs on the Stampede3 HPC system."
systemType: "LINUX"
owner: "wma_prtl"
host: "stampede3.tacc.utexas.edu"
enabled: True
effectiveUserId: "silvia"
defaultAuthnMethod: "TMS_KEYS"
authnCredential: None
bucketName: None
rootDir: "/"
port: 22
useProxy: False
proxyHost: None
proxyPort: -1
dtnSystemId: None
canExec: True
canRunBatch: True
enableCmdPrefix: True
mpiCmd: None
jobWorkingDir: "HOST_EVAL($SCRATCH)/tapis/${JobUUID}"
jobMaxJobs: 2147483647
jobMaxJobsPerUser: 2147483647
batchScheduler: "SLURM"
batchDefaultLogicalQueue: "skx"
batchSchedulerProfile: "tacc-apptainer"
importRefId: None
uuid: "2f9af736-6ab4-474f-b342-f57937f2340e"
allowChildren: False
parentId: None
deleted: False
created: "2024-02-26T21:19:26.544184Z"
updated: "2025-08-05T18:50:03.747079Z"
sharedWithUsers: []
jobRuntimes: [
{
runtimeType: "SINGULARITY"
version: None
}
]
jobEnvVariables: []
batchLogicalQueues: [
{
name: "icx"
description: None
hpcQueueName: "icx"
maxJobs: -1
maxJobsPerUser: 20
minNodeCount: 1
maxNodeCount: 32
minCoresPerNode: 1
maxCoresPerNode: 80
minMemoryMB: 1
maxMemoryMB: 256000
minMinutes: 1
maxMinutes: 2880
}
{
name: "skx"
description: None
hpcQueueName: "skx"
maxJobs: -1
maxJobsPerUser: 60
minNodeCount: 1
maxNodeCount: 256
minCoresPerNode: 1
maxCoresPerNode: 48
minMemoryMB: 1
maxMemoryMB: 192000
minMinutes: 1
maxMinutes: 2880
}
{
name: "skx-dev"
description: None
hpcQueueName: "skx-dev"
maxJobs: -1
maxJobsPerUser: 3
minNodeCount: 1
maxNodeCount: 16
minCoresPerNode: 1
maxCoresPerNode: 48
minMemoryMB: 1
maxMemoryMB: 192000
minMinutes: 1
maxMinutes: 120
}
{
name: "pvc"
description: None
hpcQueueName: "pvc"
maxJobs: -1
maxJobsPerUser: 4
minNodeCount: 1
maxNodeCount: 4
minCoresPerNode: 1
maxCoresPerNode: 96
minMemoryMB: 1
maxMemoryMB: 128000
minMinutes: 1
maxMinutes: 2880
}
{
name: "spr"
description: None
hpcQueueName: "spr"
maxJobs: -1
maxJobsPerUser: 36
minNodeCount: 1
maxNodeCount: 32
minCoresPerNode: 1
maxCoresPerNode: 112
minMemoryMB: 1
maxMemoryMB: 128000
minMinutes: 1
maxMinutes: 2880
}
{
name: "nvdimm"
description: None
hpcQueueName: "nvdimm"
maxJobs: -1
maxJobsPerUser: 3
minNodeCount: 1
maxNodeCount: 1
minCoresPerNode: 1
maxCoresPerNode: 80
minMemoryMB: 1
maxMemoryMB: 4000000
minMinutes: 1
maxMinutes: 2880
}
{
name: "h100"
description: None
hpcQueueName: "h100"
maxJobs: -1
maxJobsPerUser: 4
minNodeCount: 1
maxNodeCount: 4
minCoresPerNode: 1
maxCoresPerNode: 96
minMemoryMB: 1
maxMemoryMB: 1000000
minMinutes: 1
maxMinutes: 2880
}
]
jobCapabilities: []
tags: []
notes: {
label: "Stampede3"
}
}
########################################
Get Specs on System-Specific QUEUES#
We are going to use a utility function that will get the systm info and reformat the nested dictionary into a dataframe. You can use this info to slect your queue
get_system_queues.py
# ../OpsUtils/OpsUtils/Tapis/get_system_queues.py
def get_system_queues(t, system_id="stampede3", display=True):
"""
Retrieve and display the batch queues available on a given Tapis system.
This function queries the system definition from Tapis, extracts the list of
batch queues, builds a Pandas DataFrame for easy inspection, and optionally
displays it in a transposed format (with queue names as columns).
It also returns a dictionary keyed by queue name, so you can look up individual
queue properties programmatically.
Parameters
----------
t : Tapis
An authenticated Tapis client (from connect_tapis()).
system_id : str, default="stampede3"
The ID of the Tapis-registered system to query (such as "stampede3" on DesignSafe).
display : bool, default=True
If True, displays the transposed DataFrame of queues for easy exploration.
Returns
-------
dict
A dictionary where each key is a queue name and the value is a dictionary
of that queue's properties.
Example
-------
queues_info = get_system_queues(t, system_id="stampede3", display=True)
print(queues_info["skx-normal"])
"""
# code by Silvia Mazzoni, 2025
import pandas as pd
from tapipy.tapis import Tapis
system_def = t.systems.getSystem(systemId=system_id)
# Convert each TapisResult to a dictionary
queue_dicts = [queue.__dict__ for queue in system_def.batchLogicalQueues]
# Create the DataFrame
queues_df = pd.DataFrame(queue_dicts)
queues_df.set_index('name', inplace=True)
# Optional: display the DataFrame nicely
from IPython.display import display
# display(queues_df)
transposed_df = queues_df.T
if display:
display(transposed_df)
# Return as dictionary keyed by queue name
return {q["name"]: q for q in queue_dicts}
queue_dict = OpsUtils.get_system_queues(t,system_id="stampede3",display=True)
| name | icx | skx | skx-dev | pvc | spr | nvdimm | h100 |
|---|---|---|---|---|---|---|---|
| description | None | None | None | None | None | None | None |
| hpcQueueName | icx | skx | skx-dev | pvc | spr | nvdimm | h100 |
| maxJobs | -1 | -1 | -1 | -1 | -1 | -1 | -1 |
| maxJobsPerUser | 20 | 60 | 3 | 4 | 36 | 3 | 4 |
| minNodeCount | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| maxNodeCount | 32 | 256 | 16 | 4 | 32 | 1 | 4 |
| minCoresPerNode | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| maxCoresPerNode | 80 | 48 | 48 | 96 | 112 | 80 | 96 |
| minMemoryMB | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| maxMemoryMB | 256000 | 192000 | 192000 | 128000 | 128000 | 4000000 | 1000000 |
| minMinutes | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| maxMinutes | 2880 | 2880 | 120 | 2880 | 2880 | 2880 | 2880 |