Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

This page walks through creating a custom HPC application on DesignSafe. For background on what Tapis Apps are and how they work, see Tapis and Custom Apps.

Anatomy of a Tapis App

Custom Tapis Apps

On DesignSafe, you have two productive ways to run work on HPC systems.

Start with a public app if your workflow fits its interface. Write a custom app when you need non-standard flags, containers/modules, pre/post steps, or a lab-specific interface you’ll reuse.


A. Use an Existing (Public) App

Public apps on DesignSafe are vetted templates for common tools. They’re the fastest path to results.

Where to find them

How to run effectively

When public apps are ideal


B. Write Your Own App

Create a Tapis App when you need custom behavior, different software versions, or a specialized interface for your project.

Building blocks

  1. Wrapper (e.g., tapisjob_app.sh). Non-interactive, writes outputs to $PWD, handles launch (ibrun/mpirun/srun) and logging.

  2. app.json (required). App ID/version, execution system/type (HPC), job type (MPI/SERIAL), defaults (nodes/ppn/walltime), inputs and parameters.

  3. profile.json (optional). Modules and env vars (or use containers).

  4. Tiny test dataset for validation.

Registration and sharing

Best practices

When custom apps shine


Quick Chooser

NeedPublic appYour app
Fast start with a standard toolYes
Custom binaries, flags, or launch logicYes
Team-specific interface & defaultsYes
Minimal maintenanceYes
Full control / special dependenciesYes

Creating a Custom Tapis App

This is a comprehensive, unified guide. It walks you through creating a custom HPC-enabled Tapis app on DesignSafe that uses TACC’s environment modules (not Docker), and is launchable through both code (Python + Tapipy) and the DesignSafe GUI.

This guide ties together

This guide helps you define a reusable, shareable app that


Prerequisites


Step 1. Set Up Your App Directory

Structure your folder like this.

my-awesome-app/
├── run_analysis.py       # Your Python script
├── wrapper.sh            # Wrapper to load modules and run the script
├── app-definition.json   # Tapis app definition (for GUI + CLI)
Step 2. Your Python Code (run_analysis.py)

Example script.

import sys

if len(sys.argv) != 2:
    print("Usage: python run_analysis.py <input_file>")
    sys.exit(1)

with open(sys.argv[1], 'r') as f:
    content = f.read()

print("=== File Contents ===")
print(content)
Step 3. Wrapper Script (wrapper.sh)

This script is executed on the HPC system.

#!/bin/bash
cd $WORK/$JOB_NAME

# Load the necessary environment modules
module load python/3.9

# Run your Python script using an input file provided by the user
python run_analysis.py "$input_file"

Make it executable.

chmod +x wrapper.sh
Step 4. Tapis App Definition (app-definition.json)
{
  "id": "my-awesome-app-1.0",
  "name": "My Awesome App",
  "version": "1.0",
  "executionSystem": "designsafe.community.execution",
  "deploymentPath": "apps/my-awesome-app/1.0",
  "templatePath": "wrapper.sh",
  "executionType": "HPC",
  "runtime": "LINUX",
  "jobType": "BATCH",
  "parallelism": "SERIAL",
  "maxJobs": 10,
  "defaultMemory": "2GB",
  "defaultProcessors": 1,
  "defaultNodes": 1,
  "defaultMaxRunTime": "00:30:00",
  "deploymentSystem": "designsafe.storage.default",
  "inputs": [
    {
      "id": "input_file",
      "details": {
        "label": "Input File",
        "description": "A file to process"
      },
      "required": true,
      "inputType": "URI"
    }
  ],
  "parameters": [],
  "outputs": [
    {
      "id": "stdout.txt",
      "value": {
        "default": "stdout.txt"
      }
    }
  ],
  "tags": ["custom", "python", "designsafe"]
}
Step 5. Upload to DesignSafe/TACC

Upload your app files.

scp -r my-awesome-app/ yourusername@login.designsafe-ci.org:/work/apps/my-awesome-app/1.0

Or via the DesignSafe Data Depot, move the files to

/work/apps/my-awesome-app/1.0
Step 6. Register the App via Tapis CLI (Optional)

If you prefer CLI.

pip install tapis-cli-ng
tapis auth login
tapis apps create -F app-definition.json
tapis apps list | grep my-awesome-app
Step 7. Register and Use the App in Python with Tapipy

Authenticate and upload your files (same as above).

from tapipy.tapis import Tapis
import json

client = Tapis(
    base_url="https://designsafe.dev.tapis.io",  # or production URL
    username="your-username",
    password="your-password",
    tenant_id="designsafe"
)
client.get_tokens()

# Register the app
with open("app-definition.json") as f:
    app_def = json.load(f)

client.apps.createAppVersion(body=app_def)
Step 8. Upload an Input File
with open("example_input.txt", "rb") as f:
    client.files.insert(
        systemId="designsafe.storage.default",
        path="input/example_input.txt",
        file=f
    )
Step 9. Submit a Job from Python
job = client.jobs.submitJob(body={
    "name": "my-first-designsafe-job",
    "appId": "my-awesome-app-1.0",
    "appVersion": "1.0",
    "inputs": {
        "input_file": "tapis://designsafe.storage.default/input/example_input.txt"
    },
    "archive": True,
    "archiveSystemId": "designsafe.storage.default",
    "archivePath": "archive/my-awesome-output"
})
print("Job submitted:", job.id)
Step 10. Monitor and Download Output
import time

while True:
    status = client.jobs.getJob(jobId=job.id).status
    print("Status:", status)
    if status in ["FINISHED", "FAILED", "CANCELLED"]:
        break
    time.sleep(10)

# Download output
client.jobs.getJobOutput(jobId=job.id, path="stdout.txt", destination="./stdout.txt")
Step 11. Launch from DesignSafe GUI

Once registered

  1. Go to Workspace, then Tools & Applications, then Private Apps

  2. Click your app (“My Awesome App”)

  3. Fill in input fields (like file selectors)

  4. Launch job. Tapis runs it on Stampede3 or Frontera

  5. Results appear in your Project Data folder

Tips and Best Practices