Skip to content

Commit 239815f

Browse files
committed
Add documentation for raw tapis client and authentication error
1 parent 4654e3d commit 239815f

6 files changed

Lines changed: 1696 additions & 0 deletions

File tree

docs/api/client.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,36 @@ The main client interface for all DAPI functionality. DSClient provides organize
44

55
::: dapi.client.DSClient
66

7+
## Accessing the Raw Tapis Client
8+
9+
For advanced use cases or accessing Tapis APIs not wrapped by dapi, you can get the underlying Tapis client:
10+
11+
```python
12+
from dapi import DSClient
13+
14+
# Initialize DSClient
15+
ds = DSClient()
16+
17+
# Access the raw Tapis client
18+
tapis_client = ds.tapis
19+
20+
# Use raw Tapis APIs directly
21+
raw_apps = tapis_client.apps.getApps(search="*opensees*")
22+
systems = tapis_client.systems.getSystems()
23+
jobs = tapis_client.jobs.getJobList()
24+
```
25+
26+
### When to Use the Raw Tapis Client
27+
28+
- Access Tapis APIs not yet wrapped by dapi
29+
- Use advanced search parameters not exposed by dapi
30+
- Implement custom functionality
31+
- Debug or troubleshoot API calls
32+
- Access experimental or new Tapis features
33+
34+
!!! warning
35+
When using the raw Tapis client, you'll need to handle errors and data formatting yourself. The dapi wrapper provides error handling and user-friendly formatting.
36+
737
## Service Interfaces
838

939
The DSClient provides access to different DesignSafe services through specialized interface classes:

docs/authentication.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,27 @@ print(f"NGL database has {df.iloc[0, 0]} sites")
307307
print("✅ All authentication successful!")
308308
```
309309

310+
## 🔧 Troubleshooting
311+
312+
### JWT Token Expiration
313+
314+
If you encounter JWT token expiration errors during long-running sessions, you'll see an error like:
315+
316+
```
317+
UnauthorizedError: message: b'TAPIS_SECURITY_JWT_EXPIRED Exception message: JWT expired at 2025-06-09T08:51:38Z. Current time: 2025-06-09T12:06:54Z, a difference of 11716617 milliseconds. Allowed clock skew: 0 milliseconds. Claims: iss: https://designsafe.tapis.io/v3/tokens sub: username@designsafe tapis/tenant_id: designsafe tapis/username: username tapis/account_type: user'
318+
```
319+
320+
**Solution:** Simply reinitialize your DSClient to refresh the authentication tokens:
321+
322+
```python
323+
# Reinitialize the client to refresh tokens
324+
ds = DSClient()
325+
```
326+
327+
This will automatically handle token refresh and you can continue with your work.
328+
329+
**Why this happens:** Tapis authentication tokens have a limited lifespan for security purposes. Long-running Jupyter notebooks or scripts may encounter this after several hours of use.
330+
310331
## ➡️ Next Steps
311332

312333
After setting up authentication:

docs/examples/apps.md

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
# App Discovery and Management
2+
3+
This guide demonstrates how to discover and examine Tapis applications available on DesignSafe using the dapi library.
4+
5+
## Basic Setup
6+
7+
```python
8+
from dapi import DSClient
9+
10+
# Initialize the client (will prompt for credentials if needed)
11+
ds = DSClient()
12+
```
13+
14+
## Finding Applications
15+
16+
### Find All Available Apps
17+
18+
```python
19+
# Get a list of all available applications
20+
all_apps = ds.apps.find("", verbose=False)
21+
print(f"Found {len(all_apps)} total apps.")
22+
```
23+
24+
### Search for Specific Apps
25+
26+
```python
27+
# Search for applications containing "mpm" in the name
28+
mpm_apps = ds.apps.find("mpm", verbose=True)
29+
```
30+
31+
The `verbose=True` option will display a formatted list of matching applications with their versions and owners.
32+
33+
### Search for Other Common Applications
34+
35+
```python
36+
# Find MATLAB apps
37+
matlab_apps = ds.apps.find("matlab", verbose=True)
38+
39+
# Find OpenSees apps
40+
opensees_apps = ds.apps.find("opensees", verbose=True)
41+
42+
# Find ADCIRC apps
43+
adcirc_apps = ds.apps.find("adcirc", verbose=True)
44+
45+
# Find OpenFOAM apps
46+
openfoam_apps = ds.apps.find("openfoam", verbose=True)
47+
```
48+
49+
## Getting Application Details
50+
51+
### Basic App Information
52+
53+
```python
54+
# Get detailed information for a specific application
55+
app_id = "opensees-express"
56+
app_details = ds.apps.get_details(app_id, verbose=True)
57+
58+
if app_details:
59+
print(f"App ID: {app_details.id}")
60+
print(f"Version: {app_details.version}")
61+
print(f"Description: {app_details.description}")
62+
print(f"Owner: {app_details.owner}")
63+
print(f"Execution System: {app_details.jobAttributes.execSystemId}")
64+
else:
65+
print(f"App '{app_id}' not found")
66+
```
67+
68+
### Understanding App Parameters
69+
70+
Applications define their input requirements through parameters. Here's how to examine them:
71+
72+
```python
73+
app_details = ds.apps.get_details("opensees-express")
74+
job_attrs = app_details.jobAttributes
75+
param_set = job_attrs.parameterSet
76+
77+
# Check file inputs
78+
print("File Inputs:")
79+
for file_input in job_attrs.fileInputs:
80+
print(f" - {file_input.name}: {file_input.description}")
81+
82+
# Check app arguments
83+
print("\nApp Arguments:")
84+
for arg in param_set.appArgs:
85+
print(f" - {arg.name}: {arg.description}")
86+
87+
# Check environment variables
88+
print("\nEnvironment Variables:")
89+
for env_var in param_set.envVariables:
90+
print(f" - {env_var.key}: {env_var.description}")
91+
if hasattr(env_var, 'enum_values') and env_var.enum_values:
92+
print(f" Options: {list(env_var.enum_values.keys())}")
93+
```
94+
95+
### Resource Requirements
96+
97+
```python
98+
# Check default resource requirements
99+
job_attrs = app_details.jobAttributes
100+
print(f"Default node count: {job_attrs.nodeCount}")
101+
print(f"Default cores per node: {job_attrs.coresPerNode}")
102+
print(f"Default memory (MB): {job_attrs.memoryMB}")
103+
print(f"Default max minutes: {job_attrs.maxMinutes}")
104+
print(f"Default queue: {job_attrs.execSystemLogicalQueue}")
105+
```
106+
107+
## Working with App Data as DataFrames
108+
109+
For analysis and comparison, you can convert app data to pandas DataFrames:
110+
111+
```python
112+
import pandas as pd
113+
114+
# Get all apps and convert to DataFrame
115+
all_apps = ds.apps.find("", verbose=False)
116+
117+
# Extract basic app information
118+
app_data = []
119+
for app in all_apps:
120+
app_data.append({
121+
'id': app.id,
122+
'version': app.version,
123+
'owner': app.owner,
124+
'description': app.description,
125+
'enabled': app.enabled,
126+
'execution_system': getattr(app.jobAttributes, 'execSystemId', 'N/A'),
127+
'max_minutes': getattr(app.jobAttributes, 'maxMinutes', 'N/A'),
128+
'node_count': getattr(app.jobAttributes, 'nodeCount', 'N/A'),
129+
'cores_per_node': getattr(app.jobAttributes, 'coresPerNode', 'N/A'),
130+
})
131+
132+
apps_df = pd.DataFrame(app_data)
133+
print(apps_df.head())
134+
135+
# Filter for specific types of applications
136+
simulation_apps = apps_df[apps_df['description'].str.contains('simulation', case=False, na=False)]
137+
print(f"\nFound {len(simulation_apps)} simulation apps")
138+
```
139+
140+
## Advanced: Accessing the Raw Tapis Client
141+
142+
If you need to access Tapis APIs that aren't wrapped by dapi, you can get the underlying Tapis client:
143+
144+
```python
145+
# Get the raw Tapis client for advanced operations
146+
tapis_client = ds.tapis
147+
148+
# Example: Get raw app details using Tapis client directly
149+
raw_app_details = tapis_client.apps.getApp(appId="opensees-express")
150+
print(f"Raw app data: {raw_app_details}")
151+
152+
# Example: List apps with custom parameters
153+
raw_apps = tapis_client.apps.getApps(search="*mpm*", listType="ALL")
154+
print(f"Found {len(raw_apps)} raw apps")
155+
156+
# Example: Access other Tapis services
157+
systems = tapis_client.systems.getSystems()
158+
print(f"Available systems: {len(systems)}")
159+
```
160+
161+
### When to Use the Raw Tapis Client
162+
163+
Use `ds.tapis` when you need to:
164+
165+
- Access Tapis APIs not yet wrapped by dapi
166+
- Use advanced search parameters not exposed by dapi
167+
- Implement custom functionality
168+
- Debug or troubleshoot API calls
169+
- Access experimental or new Tapis features
170+
171+
!!! warning "Using Raw Tapis Client"
172+
When using the raw Tapis client, you'll need to handle errors and data formatting yourself. The dapi wrapper provides error handling and user-friendly formatting that you'll lose with direct Tapis calls.
173+
174+
## Common App Categories
175+
176+
Here are some common application categories available on DesignSafe:
177+
178+
```python
179+
# Structural analysis applications
180+
structural_keywords = ["opensees", "abaqus", "ansys", "ls-dyna"]
181+
182+
# Fluid dynamics applications
183+
fluid_keywords = ["openfoam", "adcirc", "swan"]
184+
185+
# Geotechnical applications
186+
geo_keywords = ["mpm", "plaxis", "flac"]
187+
188+
# Materials applications
189+
materials_keywords = ["lammps", "matlab"]
190+
191+
# Search for each category
192+
for category, keywords in [
193+
("Structural", structural_keywords),
194+
("Fluid Dynamics", fluid_keywords),
195+
("Geotechnical", geo_keywords),
196+
("Materials", materials_keywords)
197+
]:
198+
print(f"\n{category} Applications:")
199+
for keyword in keywords:
200+
apps = ds.apps.find(keyword, verbose=False)
201+
if apps:
202+
print(f" {keyword}: {len(apps)} apps found")
203+
```
204+
205+
## Next Steps
206+
207+
After discovering applications, you can:
208+
209+
1. **[Submit jobs](../jobs.md)** using the discovered applications
210+
2. **[Explore job examples](mpm.md)** for specific workflows
211+
3. **[Check system resources](../api/systems.md)** for execution requirements
212+
4. **[Manage files](../api/files.md)** for job inputs and outputs
213+
214+
## Troubleshooting
215+
216+
### App Not Found
217+
If an application isn't found, it might be:
218+
- Disabled temporarily
219+
- Only available to specific users
220+
- Spelled differently than expected
221+
222+
Try broader searches or contact DesignSafe support.
223+
224+
### Access Issues
225+
Some applications might require special permissions or allocations. Check with your project team or DesignSafe support if you can't access expected applications.

0 commit comments

Comments
 (0)