Skip to content

Commit 017cca6

Browse files
authored
Merge pull request #50 from VectorInstitute/add_admin_module
Add setup participants admin sub-command
2 parents 37b08d7 + c67a8a2 commit 017cca6

File tree

14 files changed

+2017
-7
lines changed

14 files changed

+2017
-7
lines changed

docs/cli.md

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# CLI Reference
22

3-
The `aieng-platform-onboard` package provides a command-line tool for bootcamp participant onboarding, authentication, and environment setup.
3+
The `aieng-platform-onboard` package provides a command-line tool for bootcamp participant onboarding, authentication, environment setup, and admin operations.
44

55
## Installation
66

@@ -14,6 +14,10 @@ pip install aieng-platform-onboard
1414

1515
Main command for onboarding bootcamp participants with team-specific API keys.
1616

17+
### `onboard admin`
18+
19+
Admin commands for managing participants and teams.
20+
1721
#### Usage
1822

1923
```bash
@@ -40,6 +44,66 @@ View onboarding status for all participants (requires admin credentials):
4044
onboard --admin-status-report --gcp-project coderd
4145
```
4246

47+
## Admin Commands
48+
49+
### `onboard admin setup-participants`
50+
51+
Setup participants and teams from CSV file.
52+
53+
#### Usage
54+
55+
```bash
56+
onboard admin setup-participants <csv_file> [--dry-run]
57+
```
58+
59+
#### Arguments
60+
61+
| Argument | Description | Required |
62+
|----------|-------------|----------|
63+
| `csv_file` | Path to CSV file | Yes |
64+
65+
#### CSV Format
66+
67+
Required columns:
68+
- `github_handle` - GitHub username
69+
- `team_name` - Team name
70+
71+
Optional columns:
72+
- `email` - Email address
73+
- `first_name` - First name
74+
- `last_name` - Last name
75+
76+
#### Options
77+
78+
| Option | Description |
79+
|--------|-------------|
80+
| `--dry-run` | Validate and preview changes without modifying Firestore |
81+
82+
#### Examples
83+
84+
**Setup participants from CSV:**
85+
```bash
86+
onboard admin setup-participants participants.csv
87+
```
88+
89+
**Dry run (validate only):**
90+
```bash
91+
onboard admin setup-participants participants.csv --dry-run
92+
```
93+
94+
**Sample CSV:**
95+
```csv
96+
github_handle,team_name,email,first_name,last_name
97+
alice,team-alpha,[email protected],Alice,Smith
98+
bob,team-alpha,[email protected],Bob,Jones
99+
charlie,team-beta,[email protected],Charlie,Brown
100+
```
101+
102+
#### Requirements
103+
104+
- Admin credentials (service account or gcloud auth)
105+
- Firestore write access
106+
43107
## Options
44108

45109
### Required (for participant onboarding)
@@ -133,11 +197,21 @@ onboard \
133197
### Admin Status Report
134198

135199
```bash
136-
# Requires admin credentials (service account or gcloud auth)
200+
# Requires admin credentials
137201
gcloud auth application-default login
138202
onboard --admin-status-report --gcp-project coderd
139203
```
140204

205+
### Setup Participants
206+
207+
```bash
208+
# Setup participants from CSV
209+
onboard admin setup-participants config/participants.csv
210+
211+
# Validate CSV without making changes
212+
onboard admin setup-participants config/participants.csv --dry-run
213+
```
214+
141215
## Generated Files
142216

143217
### .env File
@@ -182,4 +256,11 @@ source .env
182256
gcloud auth application-default login
183257
```
184258
- Or set `GOOGLE_APPLICATION_CREDENTIALS` to service account key path
185-
- Verify you have Firestore read access for the project
259+
- Verify you have Firestore read/write access for the project
260+
261+
### CSV Validation Errors
262+
263+
- Check CSV has required columns: `github_handle`, `team_name`
264+
- Verify GitHub handles are valid (alphanumeric and hyphens, max 39 chars)
265+
- Ensure team names are valid (alphanumeric, hyphens, underscores)
266+
- Check for duplicate GitHub handles

scripts/admin/setup_teams.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from datetime import datetime, timezone
1313
from pathlib import Path
1414

15-
from google.cloud import firestore
15+
from google.cloud import firestore # type: ignore[attr-defined]
1616
from rich.panel import Panel
1717
from rich.progress import Progress, SpinnerColumn, TextColumn
1818
from rich.table import Table

scripts/collect_coder_analytics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222

2323
try:
24-
from google.cloud import firestore, storage
24+
from google.cloud import firestore, storage # type: ignore[attr-defined]
2525
except ImportError:
2626
print("Error: google-cloud-storage or google-cloud-firestore not installed.")
2727
print("Run: pip install google-cloud-storage google-cloud-firestore")

services/token-service/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import jwt
1515
from firebase_admin import auth, credentials
1616
from flask import Flask, request
17-
from google.cloud import firestore
17+
from google.cloud import firestore # type: ignore[attr-defined]
1818

1919

2020
# Initialize Flask app
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"""Admin commands for aieng-platform-onboard."""
2+
3+
from aieng_platform_onboard.admin.cli import main as admin_main
4+
5+
6+
__all__ = ["admin_main"]
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"""Admin CLI dispatcher for aieng-platform-onboard."""
2+
3+
import argparse
4+
import sys
5+
6+
from aieng_platform_onboard.admin.setup_participants import (
7+
setup_participants_from_csv,
8+
)
9+
10+
11+
def main() -> int:
12+
"""
13+
Admin CLI entry point for admin commands.
14+
15+
Returns
16+
-------
17+
int
18+
Exit code (0 for success, 1 for failure).
19+
"""
20+
parser = argparse.ArgumentParser(
21+
prog="onboard admin",
22+
description="Admin commands for managing bootcamp participants and teams",
23+
formatter_class=argparse.RawDescriptionHelpFormatter,
24+
)
25+
26+
subparsers = parser.add_subparsers(
27+
dest="command",
28+
help="Admin command to run",
29+
required=True,
30+
)
31+
32+
# setup-participants subcommand
33+
setup_participants_parser = subparsers.add_parser(
34+
"setup-participants",
35+
help="Setup participants and teams from CSV file",
36+
description="Load participants and teams from CSV into Firestore",
37+
)
38+
setup_participants_parser.add_argument(
39+
"csv_file",
40+
type=str,
41+
help="Path to CSV file with columns: github_handle, team_name, email (optional), first_name (optional), last_name (optional)",
42+
)
43+
setup_participants_parser.add_argument(
44+
"--dry-run",
45+
action="store_true",
46+
help="Validate and show what would be done without making changes",
47+
)
48+
49+
args = parser.parse_args()
50+
51+
# Route to appropriate command handler
52+
if args.command == "setup-participants":
53+
return setup_participants_from_csv(args.csv_file, dry_run=args.dry_run)
54+
55+
# Should never reach here due to required=True
56+
parser.print_help()
57+
return 1
58+
59+
60+
if __name__ == "__main__":
61+
sys.exit(main())

0 commit comments

Comments
 (0)