Skip to content

Commit 5acf2f8

Browse files
committed
Update projects docs with DataFrame API and data source details
- Update examples to show DataFrame default output - Add "How it works" section explaining the portal API and PRJ resolution - Fix pi field description (now a display name string, not dict)
1 parent a511591 commit 5acf2f8

1 file changed

Lines changed: 43 additions & 23 deletions

File tree

docs/projects.md

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,58 @@
11
# Projects
22

3+
DesignSafe projects (MyProjects) are collaborative workspaces where team members share files, curate datasets, and publish research. Each project has a PRJ number (e.g., PRJ-6270), a UUID, and a corresponding Tapis storage system.
4+
5+
Project metadata is fetched from the [DesignSafe portal API](https://designsafe-ci.org) (`/api/projects/v2/`), which provides project details, team information, and DOIs. File listings use the Tapis Files API against the project's storage system (`project-<uuid>`).
6+
37
## List your projects
48

9+
Returns a DataFrame by default. Use `output="list"` for a list of dicts.
10+
511
```python
612
from dapi import DSClient
713
ds = DSClient()
814

9-
projects = ds.projects.list()
10-
for p in projects[:5]:
11-
pi = p['pi']
12-
pi_name = f"{pi['fname']} {pi['lname']}" if pi else "N/A"
13-
print(f"{p['projectId']:12s} | {pi_name:25s} | {p['title'][:50]}")
15+
# DataFrame (renders as a table in Jupyter)
16+
ds.projects.list()
17+
18+
# List of dicts
19+
projects = ds.projects.list(output="list")
1420
```
1521

1622
Pagination:
1723

1824
```python
19-
# Get projects 100-199
20-
projects = ds.projects.list(limit=100, offset=100)
25+
ds.projects.list(limit=100, offset=100)
2126
```
2227

28+
DataFrame columns: `projectId`, `title`, `pi`, `type`, `created`, `lastUpdated`, `uuid`.
29+
2330
## Get project details
2431

32+
Returns a dictionary with full project metadata.
33+
2534
```python
2635
info = ds.projects.get("PRJ-6270")
2736

28-
print(info['title'])
29-
print(info['description'])
30-
print(info['projectType'])
31-
print(info['pi'])
32-
print(info['dois'])
33-
print(info['keywords'])
34-
print(info['awardNumbers'])
35-
print(info['systemId']) # Tapis system ID for file access
37+
info['title']
38+
info['description']
39+
info['pi'] # PI display name (e.g., "Cheng-Hsi Hsiao")
40+
info['dois'] # Associated DOIs
41+
info['keywords']
42+
info['awardNumbers']
43+
info['projectType'] # experimental, simulation, field_recon, other, etc.
44+
info['systemId'] # Tapis system ID for file access
3645
```
3746

38-
The returned dictionary contains:
47+
Full field reference:
3948

4049
| Field | Description |
4150
|---|---|
4251
| `uuid` | Project UUID |
4352
| `projectId` | Project ID (e.g., "PRJ-6270") |
4453
| `title` | Project title |
4554
| `description` | Project description |
46-
| `pi` | Principal investigator (dict with username, fname, lname, email) |
55+
| `pi` | Principal investigator display name |
4756
| `coPis` | Co-PIs |
4857
| `teamMembers` | Team members |
4958
| `awardNumbers` | Grant/award numbers |
@@ -56,18 +65,21 @@ The returned dictionary contains:
5665

5766
## List files in a project
5867

68+
Returns a DataFrame by default. Use `output="raw"` for Tapis file objects.
69+
5970
```python
6071
# Root of a project
61-
files = ds.projects.files("PRJ-6270")
62-
for f in files:
63-
print(f"{f.name:50s} {f.type}")
72+
ds.projects.files("PRJ-6270")
6473

6574
# Subfolder
66-
files = ds.projects.files("PRJ-1305", path="/Training/")
67-
for f in files[:10]:
68-
print(f"{f.name:50s} {f.type}")
75+
ds.projects.files("PRJ-1305", path="/Training/")
76+
77+
# Raw Tapis file objects
78+
files = ds.projects.files("PRJ-6270", output="raw")
6979
```
7080

81+
DataFrame columns: `name`, `type`, `size`, `lastModified`, `path`.
82+
7183
## Projects and file path translation
7284

7385
`ds.files.to_uri()` also accepts project paths. dapi resolves the PRJ number to the Tapis system UUID automatically:
@@ -81,6 +93,14 @@ files = ds.files.list(uri)
8193

8294
Both `/MyProjects/PRJ-XXXX/` and `/projects/PRJ-XXXX/` are accepted.
8395

96+
## How it works
97+
98+
1. **Project listing and metadata** — dapi queries the DesignSafe portal API (`https://designsafe-ci.org/api/projects/v2/`) using your Tapis authentication token. This API returns project metadata including the project UUID.
99+
100+
2. **PRJ-to-UUID resolution** — Each project's Tapis storage system ID is `project-<uuid>`. When you use a PRJ number (e.g., `PRJ-6270`), dapi looks up the UUID via the portal API.
101+
102+
3. **File operations** — File listings use the standard Tapis Files API (`t.files.listFiles`) against the resolved `project-<uuid>` system.
103+
84104
## Error handling
85105

86106
- **Project not found**: raised if the PRJ number doesn't match any project you have access to.

0 commit comments

Comments
 (0)