Job Metadata#
by Silvia Mazzoni, DesignSafe, 2025
Using the job ID (uuid), you can access detailed metadata on a job via Tapis’s getJob… method.
This command is used to retrieve detailed information about specific jobs, rather than to list/filter many jobs.
We will use a python function that collects these metadata and process them to give you more informtion on output paths.
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-21T02:49:32+00:00
Token expires in: 3:39:33.642532
-- LOG IN SUCCESSFUL! --
Get detailed job metadata from Tapis#
User Input – job id#
Please enter your own jobUuid
jobUuid = '4dfa35e1-15cd-48fd-a090-f348544dee1f-007'
Get all job metadata#
get_tapis_job_metadata.py
# ../OpsUtils/OpsUtils/Tapis/get_tapis_job_metadata.py
def get_tapis_job_metadata(t, jobUuid,printAll = True):
"""
Retrieves and prints metadata for a specified Tapis job, including robust local archive reconstruction.
This function queries the Tapis jobs API for metadata on a given job, printing
details such as UUID, name, status, application ID, creation time, and archive location.
If the job has completed successfully (status == 'FINISHED'), it reconstructs
the expected local archive directory path under '~/MyData/tapis-jobs-archive',
checks whether it exists, lists its contents, and returns this information
in a structured dictionary.
If the job is not yet finished or the local directory does not exist, it prints
a notice and returns a dictionary describing the situation.
Parameters
----------
t : object
An authenticated Tapis client instance (e.g., from `tapis3`).
jobUuid : str
UUID of the job whose metadata is to be retrieved.
Returns
-------
dict
A dictionary with the following keys:
- "local_path" (str or None): local archive directory path if job is finished, else None.
- "exists" (bool): True if the local directory exists.
- "files" (list of str): list of files in the directory if it exists.
- "message" (str, optional): explanatory message if no data is available.
Prints
------
- Job UUID, name, status, appId, creation time, and archive directory.
- If finished, the reconstructed local archive path and the files contained within it,
or a notice if the local directory does not exist.
Example
-------
>>> result = get_tapis_job_metadata(t, "a1b2c3d4-5678-90ef-ghij-klmnopqrstuv")
>>> if result["exists"]:
... print("Archived job data at:", result["local_path"])
... print("Files:", result["files"])
... else:
... print(result.get("message", "Job not yet completed."))
"""
# Silvia Mazzoni, 2025
import os
import json
if printAll:
import ipywidgets as widgets
from IPython.display import display, clear_output
metadata_out = widgets.Output()
metadata_accordion = widgets.Accordion(children=[metadata_out])
metadata_accordion.set_title(0, f'Job Metadata ({jobUuid})')
metadata_accordion.selected_index = 0
display(metadata_accordion)
job_response = t.jobs.getJob(jobUuid=jobUuid)
job_dict_all = json.loads(json.dumps(job_response, default=lambda o: vars(o)))
if printAll:
with metadata_out:
# print('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
print('+++++++++++++++++++++++++')
print('++++++ Job Metadata')
print('+++++++++++++++++++++++++')
print('+ uuid: ', job_response.uuid)
print('+ name: ', job_response.name)
print('+ status: ', job_response.status)
print('+ appId: ', job_response.appId)
print('+ created: ', job_response.created)
print('+ output-file location')
print('+ archiveSystemId:', job_response.archiveSystemId)
print('+ archiveSystemDir:', job_response.archiveSystemDir)
# ------
execSystemId = job_response.execSystemId
archiveSystemId = job_response.archiveSystemId
sysPath = ''
if archiveSystemId == 'designsafe.storage.default':
sysPath = 'MyData';
elif archiveSystemId in ['Work','work','cloud.data','stampede3',execSystemId]:
sysPath = f'Work/{execSystemId}';
if archiveSystemId == 'designsafe.storage.community':
sysPath = 'CommunityData'; ## but you can't write to community
if archiveSystemId == 'designsafe.storage.published':
sysPath = 'Published'; ## but you can't write to published!
archiveSystemDir = job_dict_all['archiveSystemDir']
archiveSystemDir_user = archiveSystemDir.split('tapis-jobs-archive'+os.path.sep)[1] # remove the first character slash
archiveSystemDir_user = os.path.join(sysPath,'tapis-jobs-archive',archiveSystemDir_user)
archiveSystemDir_out = archiveSystemDir_user
if job_response.appId in ["opensees-mp-s3","opensees-sp-s3"]:
archiveSystemDir_out = os.path.join(archiveSystemDir_out,'inputDirectory')
elif job_response.appId in ["opensees-express"]:
fileInputsList = json.loads(job_dict_all['fileInputs'])
for fileInputs in fileInputsList:
if fileInputs['name'] in ['Input Directory'] or fileInputs['envKey'] in ['inputDirectory']:
sourceUrl = fileInputs['sourceUrl']
input_folder_end = os.path.basename(sourceUrl)
archiveSystemDir_out = os.path.join(archiveSystemDir_user,input_folder_end)
break
# if sysPath != '':
archiveSystemDir_user = os.path.expanduser(os.path.join('~',archiveSystemDir_user))
archiveSystemDir_out = os.path.expanduser(os.path.join('~',archiveSystemDir_out))
job_dict_all['archiveSystemDir_user'] = archiveSystemDir_user
job_dict_all['archiveSystemDir_out'] = archiveSystemDir_out
if printAll:
with metadata_out:
print('+ archiveSystemDir_user:', job_dict_all['archiveSystemDir_user'])
print('+ archiveSystemDir_out:', job_dict_all['archiveSystemDir_out'])
JobInfoKeys = ['','uuid','name','','status','remoteOutcome','condition','lastMessage','','execSystemId','execSystemExecDir','execSystemOutputDir','','appId','appVersion','','tenant','trackingId','createdby','created','description','','execSystemId','execSystemLogicalQueue','nodeCount','coresPerNode','maxMinutes','memoryMB']
# print('\n-- Additional Relevant Job Metadata --')
print('+ ++++++++++++++++++++++++')
print('+ +++++ Additional Relevant Job Metadata')
print('+ ++++++++++++++++++++++++')
for thisKey in JobInfoKeys:
if thisKey in job_dict_all.keys():
thisValue = job_dict_all[thisKey]
# myJobTapisData[thisKey] = thisValue
print(f'+ - {thisKey}: {thisValue}')
else:
print('+ ----------------------')
print('+ ++++++++++++++++++++++++')
if 'fileInputs' in job_dict_all.keys():
this_out = widgets.Output()
this_accordion = widgets.Accordion(children=[this_out])
this_accordion.set_title(0, f'fileInputs')
# this_accordion.selected_index = 0
with metadata_out:
display(this_accordion)
with this_out:
print('')
print('#'*32)
print('### fileInputs')
print('#'*32)
fileInputsList = json.loads(job_dict_all['fileInputs'])
for thisLine in fileInputsList:
print('# ' + '+'*30)
for thisKey,thisKeyVal in thisLine.items():
print(f'# + {thisKey} = {thisKeyVal}')
print('# ' + '+'*30)
print('#'*32)
if 'parameterSet' in job_dict_all.keys():
this_out = widgets.Output()
this_accordion = widgets.Accordion(children=[this_out])
this_accordion.set_title(0, f'parameterSet')
# this_accordion.selected_index = 0
with metadata_out:
display(this_accordion)
with this_out:
print('')
print('#'*32)
print('### parameterSet')
print('#'*32)
parameterSetDict = json.loads(job_dict_all['parameterSet'])
for thisLineKey,thisLineValues in parameterSetDict.items():
print('#')
print('# ' + '+'*30)
print(f'# ++ {thisLineKey} ')
print('# ' + '+'*30)
if isinstance(thisLineValues, list):
for thisLine in thisLineValues:
print('# ' + '+ ' + '-'*28)
if isinstance(thisLine, dict):
for thisKey,thisVal in thisLine.items():
if thisVal != None:
print(f'# + - {thisKey} : {thisVal}')
else:
print('####################not dict',thisLine)
print('# ' + '+ ' + '-'*28)
elif isinstance(thisLineValues, dict):
for thisKey,thisVal in thisLineValues.items():
if thisVal != None:
print(f'# + {thisKey} : {thisVal}')
else:
print('not list nor dict',thisLine)
print('# ' + '+'*30)
print('#'*32)
return job_dict_all
JobMetadata = OpsUtils.get_tapis_job_metadata(t,jobUuid)
JobMetadata = OpsUtils.get_tapis_job_metadata(t,'5d2d6e55-3074-4632-8e8d-1ed63a730f5f-007') # opensees-express job
JobMetadata = OpsUtils.get_tapis_job_metadata(t,'b35ab3c2-0436-4c98-9066-367b9db67f9c-007') # this job was submitted and failed
JobMetadata = OpsUtils.get_tapis_job_metadata(t,'a3c514c4-d488-40d0-9efe-0e0a77039033-007') # this job also failed
Collect Metadata for your own processing#
jobUuid = '4dfa35e1-15cd-48fd-a090-f348544dee1f-007'
JobMetadata = OpsUtils.get_tapis_job_metadata(t,jobUuid,printAll=False) # don't print, we will look at the data
SCRATCH-Folder path#
This is the location where the work was actually done!
This is where you can find your files while the job is running as well as if file-transfer to the archive path failed
execSystemOutputDir = JobMetadata['execSystemOutputDir']
print('execSystemOutputDir',execSystemOutputDir)
execSystemOutputDir /scratch/05072/silvia/tapis/4dfa35e1-15cd-48fd-a090-f348544dee1f-007
ARCHIVE-Folder path#
This is the location where the final location of your job files.
They are transferred here from the scratch path, you can now move them to your desired location.
archiveSystemDir = JobMetadata['archiveSystemDir']
print('archiveSystemDir',archiveSystemDir)
if os.path.exists(archiveSystemDir):
print(os.listdir(archiveSystemDir))
else:
print('no such directory')
archiveSystemDir /silvia/tapis-jobs-archive/2025-05-07Z/opensees-mp-s3-latest_2025-05-07T22:13:08-4dfa35e1-15cd-48fd-a090-f348544dee1f-007
no such directory
archiveSystemDir_user = JobMetadata['archiveSystemDir_user']
print('archiveSystemDir_user',archiveSystemDir_user)
if os.path.exists(archiveSystemDir_user):
print(os.listdir(archiveSystemDir_user))
else:
print('no such directory')
archiveSystemDir_user /home/jupyter/MyData/tapis-jobs-archive/2025-05-07Z/opensees-mp-s3-latest_2025-05-07T22:13:08-4dfa35e1-15cd-48fd-a090-f348544dee1f-007
['inputDirectory', 'tapisjob.sh', 'opensees.zip', 'tapisjob.env', 'tapisjob.out', 'tapisjob_app.sh', '.ipynb_checkpoints']
archiveSystemDir_out = JobMetadata['archiveSystemDir_out']
print('archiveSystemDir_out',archiveSystemDir_out)
if os.path.exists(archiveSystemDir_out):
print(os.listdir(archiveSystemDir_out))
else:
print('no such directory')
archiveSystemDir_out /home/jupyter/MyData/tapis-jobs-archive/2025-05-07Z/opensees-mp-s3-latest_2025-05-07T22:13:08-4dfa35e1-15cd-48fd-a090-f348544dee1f-007/inputDirectory
['DataTCLmp', 'Ex1a.tcl.Canti2D.Push.mp.tcl', 'Ex1many_end.tcl.Canti2D.Push.mp.tcl', '.ipynb_checkpoints', 'Ex1many-Copy1.tcl.Canti2D.Push.mp.tcl', 'Ex1a.py.Canti2D.Push.py', 'Ex1a.tcl.Canti2D.Push.tcl', 'Ex1many_start.tcl.Canti2D.Push.mp.tcl', 'Ex1a.py.Canti2D.Push.mpi4py.py', 'Ex1a.py.Canti2D.Push.mpi.py']
Display all Metadata#
display(JobMetadata)
{'id': 42126,
'name': 'opensees-mp-s3-latest_2025-05-07T22:13:08',
'owner': 'silvia',
'tenant': 'designsafe',
'description': 'opensees-mp-s3-latest submitted by silvia@designsafe',
'status': 'FINISHED',
'condition': 'NORMAL_COMPLETION',
'lastMessage': 'Setting job status to FINISHED.',
'created': '2025-05-07T22:15:14.785522Z',
'ended': '2025-05-07T22:20:52.718025Z',
'lastUpdated': '2025-05-07T22:20:52.718025Z',
'uuid': '4dfa35e1-15cd-48fd-a090-f348544dee1f-007',
'appId': 'opensees-mp-s3',
'appVersion': 'latest',
'archiveOnAppError': True,
'dynamicExecSystem': False,
'execSystemId': 'stampede3',
'execSystemExecDir': '/scratch/05072/silvia/tapis/4dfa35e1-15cd-48fd-a090-f348544dee1f-007',
'execSystemInputDir': '/scratch/05072/silvia/tapis/4dfa35e1-15cd-48fd-a090-f348544dee1f-007',
'execSystemOutputDir': '/scratch/05072/silvia/tapis/4dfa35e1-15cd-48fd-a090-f348544dee1f-007',
'execSystemLogicalQueue': 'skx-dev',
'archiveSystemId': 'designsafe.storage.default',
'archiveSystemDir': '/silvia/tapis-jobs-archive/2025-05-07Z/opensees-mp-s3-latest_2025-05-07T22:13:08-4dfa35e1-15cd-48fd-a090-f348544dee1f-007',
'dtnSystemId': None,
'dtnSystemInputDir': None,
'dtnSystemOutputDir': None,
'nodeCount': 2,
'coresPerNode': 48,
'memoryMB': 192000,
'maxMinutes': 100,
'fileInputs': '[{"name": "Input Directory", "notes": "{\\"selectionMode\\":\\"directory\\"}", "envKey": "inputDirectory", "optional": false, "sourceUrl": "tapis://designsafe.storage.default/silvia/OpenSees/repos/training-OpenSees-on-DesignSafe/_static/OpenSeesScripts", "targetPath": "inputDirectory", "description": "Input directory that includes the tcl script as well as any other required files. Example input is in tapis://designsafe.storage.community/app_examples/opensees/OpenSeesMP", "autoMountLocal": true, "srcSharedAppCtx": "", "destSharedAppCtx": "wma_prtl"}]',
'parameterSet': '{"appArgs": [{"arg": "OpenSeesMP", "name": "mainProgram", "notes": "{\\"isHidden\\":true}", "include": null, "description": null}, {"arg": "Ex1many_end.tcl.Canti2D.Push.mp.tcl", "name": "Main Script", "notes": "{\\"inputType\\":\\"fileInput\\"}", "include": null, "description": "The filename only of the OpenSees TCL script to execute. This file should reside in the Input Directory specified. To use with test input, use \'freeFieldEffective.tcl\'"}], "logConfig": {"stderrFilename": "tapisjob.out", "stdoutFilename": "tapisjob.out"}, "envVariables": [{"key": "_tapisAppId", "notes": null, "value": "opensees-mp-s3", "include": null, "description": null}, {"key": "_tapisAppVersion", "notes": null, "value": "latest", "include": null, "description": null}, {"key": "_tapisArchiveOnAppError", "notes": null, "value": "true", "include": null, "description": null}, {"key": "_tapisArchiveSystemDir", "notes": null, "value": "/silvia/tapis-jobs-archive/2025-05-07Z/opensees-mp-s3-latest_2025-05-07T22:13:08-4dfa35e1-15cd-48fd-a090-f348544dee1f-007", "include": null, "description": null}, {"key": "_tapisArchiveSystemId", "notes": null, "value": "designsafe.storage.default", "include": null, "description": null}, {"key": "_tapisCoresPerNode", "notes": null, "value": "48", "include": null, "description": null}, {"key": "_tapisDynamicExecSystem", "notes": null, "value": "false", "include": null, "description": null}, {"key": "_tapisEffectiveUserId", "notes": null, "value": "silvia", "include": null, "description": null}, {"key": "_tapisExecSystemExecDir", "notes": null, "value": "/scratch/05072/silvia/tapis/4dfa35e1-15cd-48fd-a090-f348544dee1f-007", "include": null, "description": null}, {"key": "_tapisExecSystemHPCQueue", "notes": null, "value": "skx-dev", "include": null, "description": null}, {"key": "_tapisExecSystemId", "notes": null, "value": "stampede3", "include": null, "description": null}, {"key": "_tapisExecSystemInputDir", "notes": null, "value": "/scratch/05072/silvia/tapis/4dfa35e1-15cd-48fd-a090-f348544dee1f-007", "include": null, "description": null}, {"key": "_tapisExecSystemLogicalQueue", "notes": null, "value": "skx-dev", "include": null, "description": null}, {"key": "_tapisExecSystemOutputDir", "notes": null, "value": "/scratch/05072/silvia/tapis/4dfa35e1-15cd-48fd-a090-f348544dee1f-007", "include": null, "description": null}, {"key": "_tapisJobCreateDate", "notes": null, "value": "2025-05-07Z", "include": null, "description": null}, {"key": "_tapisJobCreateTime", "notes": null, "value": "22:15:14.785522177Z", "include": null, "description": null}, {"key": "_tapisJobCreateTimestamp", "notes": null, "value": "2025-05-07T22:15:14.785522177Z", "include": null, "description": null}, {"key": "_tapisJobName", "notes": null, "value": "opensees-mp-s3-latest_2025-05-07T22:13:08", "include": null, "description": null}, {"key": "_tapisJobOwner", "notes": null, "value": "silvia", "include": null, "description": null}, {"key": "_tapisJobUUID", "notes": null, "value": "4dfa35e1-15cd-48fd-a090-f348544dee1f-007", "include": null, "description": null}, {"key": "_tapisJobWorkingDir", "notes": null, "value": "/scratch/05072/silvia/tapis/4dfa35e1-15cd-48fd-a090-f348544dee1f-007", "include": null, "description": null}, {"key": "_tapisMaxMinutes", "notes": null, "value": "100", "include": null, "description": null}, {"key": "_tapisMemoryMB", "notes": null, "value": "192000", "include": null, "description": null}, {"key": "_tapisNodes", "notes": null, "value": "2", "include": null, "description": null}, {"key": "_tapisStderrFilename", "notes": null, "value": "tapisjob.out", "include": null, "description": null}, {"key": "_tapisStdoutFilename", "notes": null, "value": "tapisjob.out", "include": null, "description": null}, {"key": "_tapisSysBatchScheduler", "notes": null, "value": "SLURM", "include": null, "description": null}, {"key": "_tapisSysHost", "notes": null, "value": "stampede3.tacc.utexas.edu", "include": null, "description": null}, {"key": "_tapisSysRootDir", "notes": null, "value": "/", "include": null, "description": null}, {"key": "_tapisTenant", "notes": null, "value": "designsafe", "include": null, "description": null}, {"key": "inputDirectory", "notes": "{}", "value": "inputDirectory", "include": true, "description": "EnvKey from input file: Input Directory"}], "archiveFilter": {"excludes": [], "includes": [], "includeLaunchFiles": true}, "containerArgs": [], "schedulerOptions": [{"arg": "--tapis-profile OpenSees_default", "name": "OpenSees TACC Scheduler Profile", "notes": "{\\"isHidden\\":true}", "include": null, "description": "Scheduler profile for the default version of OpenSees"}, {"arg": "-A DS-HPC1", "name": "TACC Allocation", "notes": null, "include": null, "description": "The TACC allocation associated with this job execution"}]}',
'execSystemConstraints': None,
'subscriptions': '[{"enabled": true, "ttlMinutes": 10080, "description": "Portal job status notification", "deliveryTargets": [{"deliveryMethod": "WEBHOOK", "deliveryAddress": "https://www.designsafe-ci.org/webhooks/jobs/"}], "eventCategoryFilter": "JOB_NEW_STATUS"}]',
'blockedCount': 0,
'remoteJobId': '1874224',
'remoteJobId2': None,
'remoteOutcome': 'FINISHED',
'remoteResultInfo': '0:0',
'remoteQueue': None,
'remoteSubmitted': '2025-05-07T22:16:49.606851Z',
'remoteStarted': '2025-05-07T22:16:51.791782Z',
'remoteEnded': '2025-05-07T22:17:17.601968Z',
'remoteSubmitRetries': 0,
'remoteChecksSuccess': 4,
'remoteChecksFailed': 0,
'remoteLastStatusCheck': '2025-05-07T22:17:17.595078Z',
'inputTransactionId': '2510a293-a91d-481c-baf3-4f89a9ed998a',
'inputCorrelationId': '6a36ee1d-2b05-4380-a221-e27dd8bd66b0',
'archiveTransactionId': 'ad89111a-222a-4e71-9fd2-4691f15cafed',
'archiveCorrelationId': '2f7852d4-9c67-470d-aef0-64d1341f1f5f',
'stageAppTransactionId': '0e2ea3d8-1093-42f0-b8d9-7a3c9d185b33',
'stageAppCorrelationId': 'b616a64e-a8f6-4a65-9ed0-cb3e29a58869',
'dtnInputTransactionId': None,
'dtnInputCorrelationId': None,
'dtnOutputTransactionId': None,
'dtnOutputCorrelationId': None,
'tapisQueue': 'tapis.jobq.submit.DefaultQueue',
'visible': True,
'createdby': 'silvia',
'createdbyTenant': 'designsafe',
'tags': ['portalName: DESIGNSAFE'],
'jobType': 'BATCH',
'isMpi': False,
'mpiCmd': None,
'cmdPrefix': None,
'sharedAppCtx': 'wma_prtl',
'sharedAppCtxAttribs': ['SAC_EXEC_SYSTEM_ID',
'SAC_EXEC_SYSTEM_INPUT_DIR',
'SAC_EXEC_SYSTEM_EXEC_DIR',
'SAC_EXEC_SYSTEM_OUTPUT_DIR'],
'trackingId': 'portals.tjpzgzipxddro0y9h1f8iqna904lyphy',
'notes': '{"icon": "OpenSees", "label": "OpenSeesMP", "helpUrl": "https://www.designsafe-ci.org/user-guide/tools/simulation/#opensees-user-guide", "category": "Simulation", "isInteractive": false, "hideNodeCountAndCoresPerNode": false}',
'_fileInputsSpec': None,
'_parameterSetModel': None,
'archiveSystemDir_user': '/home/jupyter/MyData/tapis-jobs-archive/2025-05-07Z/opensees-mp-s3-latest_2025-05-07T22:13:08-4dfa35e1-15cd-48fd-a090-f348544dee1f-007',
'archiveSystemDir_out': '/home/jupyter/MyData/tapis-jobs-archive/2025-05-07Z/opensees-mp-s3-latest_2025-05-07T22:13:08-4dfa35e1-15cd-48fd-a090-f348544dee1f-007/inputDirectory'}
import json
print('#'*32)
print('### fileInputs')
print('#'*32)
fileInputsList = json.loads(JobMetadata['fileInputs'])
for thisLine in fileInputsList:
print('# ' + '+'*30)
for thisKey,thisKeyVal in thisLine.items():
print(f'# + {thisKey} = {thisKeyVal}')
print('# ' + '+'*30)
print('#'*32)
################################
### fileInputs
################################
# ++++++++++++++++++++++++++++++
# + name = Input Directory
# + notes = {"selectionMode":"directory"}
# + envKey = inputDirectory
# + optional = False
# + sourceUrl = tapis://designsafe.storage.default/silvia/OpenSees/repos/training-OpenSees-on-DesignSafe/_static/OpenSeesScripts
# + targetPath = inputDirectory
# + description = Input directory that includes the tcl script as well as any other required files. Example input is in tapis://designsafe.storage.community/app_examples/opensees/OpenSeesMP
# + autoMountLocal = True
# + srcSharedAppCtx =
# + destSharedAppCtx = wma_prtl
# ++++++++++++++++++++++++++++++
################################
import json
print('#'*32)
print('### parameterSet')
print('#'*32)
parameterSetDict = json.loads(JobMetadata['parameterSet'])
for thisLineKey,thisLineValues in parameterSetDict.items():
print('#')
print('# ' + '+'*30)
print(f'# ++ {thisLineKey} ')
print('# ' + '+'*30)
if isinstance(thisLineValues, list):
for thisLine in thisLineValues:
print('# ' + '+ ' + '-'*28)
if isinstance(thisLine, dict):
for thisKey,thisVal in thisLine.items():
if thisVal != None:
print(f'# + - {thisKey} : {thisVal}')
else:
print('####################not dict',thisLine)
print('# ' + '+ ' + '-'*28)
elif isinstance(thisLineValues, dict):
for thisKey,thisVal in thisLineValues.items():
if thisVal != None:
print(f'# + {thisKey} : {thisVal}')
else:
print('not list nor dict',thisLine)
print('# ' + '+'*30)
print('#'*32)
################################
### parameterSet
################################
#
# ++++++++++++++++++++++++++++++
# ++ appArgs
# ++++++++++++++++++++++++++++++
# + ----------------------------
# + - arg : OpenSeesMP
# + - name : mainProgram
# + - notes : {"isHidden":true}
# + ----------------------------
# + ----------------------------
# + - arg : Ex1many_end.tcl.Canti2D.Push.mp.tcl
# + - name : Main Script
# + - notes : {"inputType":"fileInput"}
# + - description : The filename only of the OpenSees TCL script to execute. This file should reside in the Input Directory specified. To use with test input, use 'freeFieldEffective.tcl'
# + ----------------------------
# ++++++++++++++++++++++++++++++
#
# ++++++++++++++++++++++++++++++
# ++ logConfig
# ++++++++++++++++++++++++++++++
# + stderrFilename : tapisjob.out
# + stdoutFilename : tapisjob.out
# ++++++++++++++++++++++++++++++
#
# ++++++++++++++++++++++++++++++
# ++ envVariables
# ++++++++++++++++++++++++++++++
# + ----------------------------
# + - key : _tapisAppId
# + - value : opensees-mp-s3
# + ----------------------------
# + ----------------------------
# + - key : _tapisAppVersion
# + - value : latest
# + ----------------------------
# + ----------------------------
# + - key : _tapisArchiveOnAppError
# + - value : true
# + ----------------------------
# + ----------------------------
# + - key : _tapisArchiveSystemDir
# + - value : /silvia/tapis-jobs-archive/2025-05-07Z/opensees-mp-s3-latest_2025-05-07T22:13:08-4dfa35e1-15cd-48fd-a090-f348544dee1f-007
# + ----------------------------
# + ----------------------------
# + - key : _tapisArchiveSystemId
# + - value : designsafe.storage.default
# + ----------------------------
# + ----------------------------
# + - key : _tapisCoresPerNode
# + - value : 48
# + ----------------------------
# + ----------------------------
# + - key : _tapisDynamicExecSystem
# + - value : false
# + ----------------------------
# + ----------------------------
# + - key : _tapisEffectiveUserId
# + - value : silvia
# + ----------------------------
# + ----------------------------
# + - key : _tapisExecSystemExecDir
# + - value : /scratch/05072/silvia/tapis/4dfa35e1-15cd-48fd-a090-f348544dee1f-007
# + ----------------------------
# + ----------------------------
# + - key : _tapisExecSystemHPCQueue
# + - value : skx-dev
# + ----------------------------
# + ----------------------------
# + - key : _tapisExecSystemId
# + - value : stampede3
# + ----------------------------
# + ----------------------------
# + - key : _tapisExecSystemInputDir
# + - value : /scratch/05072/silvia/tapis/4dfa35e1-15cd-48fd-a090-f348544dee1f-007
# + ----------------------------
# + ----------------------------
# + - key : _tapisExecSystemLogicalQueue
# + - value : skx-dev
# + ----------------------------
# + ----------------------------
# + - key : _tapisExecSystemOutputDir
# + - value : /scratch/05072/silvia/tapis/4dfa35e1-15cd-48fd-a090-f348544dee1f-007
# + ----------------------------
# + ----------------------------
# + - key : _tapisJobCreateDate
# + - value : 2025-05-07Z
# + ----------------------------
# + ----------------------------
# + - key : _tapisJobCreateTime
# + - value : 22:15:14.785522177Z
# + ----------------------------
# + ----------------------------
# + - key : _tapisJobCreateTimestamp
# + - value : 2025-05-07T22:15:14.785522177Z
# + ----------------------------
# + ----------------------------
# + - key : _tapisJobName
# + - value : opensees-mp-s3-latest_2025-05-07T22:13:08
# + ----------------------------
# + ----------------------------
# + - key : _tapisJobOwner
# + - value : silvia
# + ----------------------------
# + ----------------------------
# + - key : _tapisJobUUID
# + - value : 4dfa35e1-15cd-48fd-a090-f348544dee1f-007
# + ----------------------------
# + ----------------------------
# + - key : _tapisJobWorkingDir
# + - value : /scratch/05072/silvia/tapis/4dfa35e1-15cd-48fd-a090-f348544dee1f-007
# + ----------------------------
# + ----------------------------
# + - key : _tapisMaxMinutes
# + - value : 100
# + ----------------------------
# + ----------------------------
# + - key : _tapisMemoryMB
# + - value : 192000
# + ----------------------------
# + ----------------------------
# + - key : _tapisNodes
# + - value : 2
# + ----------------------------
# + ----------------------------
# + - key : _tapisStderrFilename
# + - value : tapisjob.out
# + ----------------------------
# + ----------------------------
# + - key : _tapisStdoutFilename
# + - value : tapisjob.out
# + ----------------------------
# + ----------------------------
# + - key : _tapisSysBatchScheduler
# + - value : SLURM
# + ----------------------------
# + ----------------------------
# + - key : _tapisSysHost
# + - value : stampede3.tacc.utexas.edu
# + ----------------------------
# + ----------------------------
# + - key : _tapisSysRootDir
# + - value : /
# + ----------------------------
# + ----------------------------
# + - key : _tapisTenant
# + - value : designsafe
# + ----------------------------
# + ----------------------------
# + - key : inputDirectory
# + - notes : {}
# + - value : inputDirectory
# + - include : True
# + - description : EnvKey from input file: Input Directory
# + ----------------------------
# ++++++++++++++++++++++++++++++
#
# ++++++++++++++++++++++++++++++
# ++ archiveFilter
# ++++++++++++++++++++++++++++++
# + excludes : []
# + includes : []
# + includeLaunchFiles : True
# ++++++++++++++++++++++++++++++
#
# ++++++++++++++++++++++++++++++
# ++ containerArgs
# ++++++++++++++++++++++++++++++
# ++++++++++++++++++++++++++++++
#
# ++++++++++++++++++++++++++++++
# ++ schedulerOptions
# ++++++++++++++++++++++++++++++
# + ----------------------------
# + - arg : --tapis-profile OpenSees_default
# + - name : OpenSees TACC Scheduler Profile
# + - notes : {"isHidden":true}
# + - description : Scheduler profile for the default version of OpenSees
# + ----------------------------
# + ----------------------------
# + - arg : -A DS-HPC1
# + - name : TACC Allocation
# + - description : The TACC allocation associated with this job execution
# + ----------------------------
# ++++++++++++++++++++++++++++++
################################