google-colab-cli 0.5.6__tar.gz → 0.5.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. google_colab_cli-0.5.8/PKG-INFO +203 -0
  2. google_colab_cli-0.5.8/README.md +181 -0
  3. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/docs/04_automation_and_utility.md +41 -11
  4. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/pyproject.toml +7 -3
  5. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/auto_update.py +29 -7
  6. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/cli.py +4 -0
  7. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/commands/run.py +1 -1
  8. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/commands/session.py +7 -4
  9. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/commands/utility.py +87 -16
  10. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/runtime.py +1 -1
  11. google_colab_cli-0.5.8/tests/test_readme.py +92 -0
  12. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_update.py +131 -10
  13. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_url.py +121 -18
  14. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/uv.lock +9 -7
  15. google_colab_cli-0.5.6/PKG-INFO +0 -120
  16. google_colab_cli-0.5.6/README.md +0 -95
  17. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/.githooks/pre-commit +0 -0
  18. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/.gitignore +0 -0
  19. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/.pre-commit-config.yaml +0 -0
  20. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/.python-version +0 -0
  21. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/AGENTS.md +0 -0
  22. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/COLAB_SKILL.md +0 -0
  23. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/CONTRIBUTING.md +0 -0
  24. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/LICENSE +0 -0
  25. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/cloudbuild.yaml +0 -0
  26. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/docs/01_session_management.md +0 -0
  27. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/docs/02_execution_and_interactive.md +0 -0
  28. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/docs/03_file_management.md +0 -0
  29. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/docs/05_run_command.md +0 -0
  30. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/docs/3042ab12-2026-05-07.png +0 -0
  31. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/docs/demos.md +0 -0
  32. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/integration/README.md +0 -0
  33. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/integration/repro_keep_alive/test.sh +0 -0
  34. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/integration/repro_keep_alive_scope/test.sh +0 -0
  35. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/integration/repro_piped_console/test.sh +0 -0
  36. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/integration/repro_plot_redirection/test.sh +0 -0
  37. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/integration/repro_run_command/test.sh +0 -0
  38. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/integration/repro_variable_persistence/test.sh +0 -0
  39. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/auth.py +0 -0
  40. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/client.py +0 -0
  41. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/commands/__init__.py +0 -0
  42. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/commands/automation.py +0 -0
  43. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/commands/execution.py +0 -0
  44. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/commands/files.py +0 -0
  45. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/common.py +0 -0
  46. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/console.py +0 -0
  47. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/contents.py +0 -0
  48. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/converter.py +0 -0
  49. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/history.py +0 -0
  50. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/repl.py +0 -0
  51. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/state.py +0 -0
  52. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/src/colab_cli/utils.py +0 -0
  53. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/conftest.py +0 -0
  54. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_auth.py +0 -0
  55. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_auth_adc.py +0 -0
  56. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_automation.py +0 -0
  57. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_cli.py +0 -0
  58. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_cli_log.py +0 -0
  59. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_client.py +0 -0
  60. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_console.py +0 -0
  61. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_contents.py +0 -0
  62. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_exec.py +0 -0
  63. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_history.py +0 -0
  64. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_ipynb_exec.py +0 -0
  65. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_keep_alive.py +0 -0
  66. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_log_export.py +0 -0
  67. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_pay.py +0 -0
  68. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_repl.py +0 -0
  69. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_resolution_logic.py +0 -0
  70. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_run.py +0 -0
  71. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_runtime.py +0 -0
  72. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_state.py +0 -0
  73. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_streaming.py +0 -0
  74. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_utils.py +0 -0
  75. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_version.py +0 -0
  76. {google_colab_cli-0.5.6 → google_colab_cli-0.5.8}/tests/test_whoami.py +0 -0
@@ -0,0 +1,203 @@
1
+ Metadata-Version: 2.4
2
+ Name: google-colab-cli
3
+ Version: 0.5.8
4
+ Summary: CLI for interacting with Colab.
5
+ License-File: LICENSE
6
+ Requires-Python: >=3.13
7
+ Requires-Dist: click>=8.0
8
+ Requires-Dist: google-auth-oauthlib>=1.3.0
9
+ Requires-Dist: google-auth>=2.49.1
10
+ Requires-Dist: jupyter-kernel-client
11
+ Requires-Dist: nbformat>=5.10.4
12
+ Requires-Dist: packaging>=24.0
13
+ Requires-Dist: prompt-toolkit>=3.0.52
14
+ Requires-Dist: pydantic>=2.12.5
15
+ Requires-Dist: pygments>=2.19.2
16
+ Requires-Dist: requests>=2.32.5
17
+ Requires-Dist: rich>=14.3.3
18
+ Requires-Dist: typer>=0.24.1
19
+ Requires-Dist: typing-extensions>=4.0
20
+ Requires-Dist: websocket-client>=1.0
21
+ Description-Content-Type: text/markdown
22
+
23
+ # Colab CLI
24
+
25
+ A command-line interface for Google Colab. Provision high-performance CPU, GPU, and TPU runtimes, execute local code, manage remote files, and orchestrate automated cloud pipelines — directly from your terminal.
26
+
27
+ Designed to support seamless developer productivity, headless automation, and AI agent integrations.
28
+
29
+ ---
30
+
31
+ ## Key Features
32
+
33
+ * **Instant VM Provisioning:** Spin up CPU, GPU (T4, L4, G4, H100, A100), or TPU (v5e1, v6e1) runtimes in seconds.
34
+ * **Robust Code Execution:** Run local Python scripts, Jupyter Notebooks (`.ipynb`), or piped `stdin` code; launch interactive REPLs or raw TTY console shells.
35
+ * **Ephemeral Job Runner (`colab run`):** Provision a fresh VM, execute a local script with forwarded arguments, retrieve output files, and automatically tear down the runtime in a single command.
36
+ * **Automatic Keep-Alive:** Built-in background daemon automatically prevents idle VM termination, keeping resource allocations active without requiring open browser tabs.
37
+ * **Seamless Workspace Automation:** Mount Google Drive, authenticate Google Cloud Platform (GCP) credentials, and install dependencies with high-performance `uv` package management.
38
+ * **State & Log Archival:** Inspect local session states or export interactive history logs to standard Jupyter Notebooks, Markdown, or structured JSONL.
39
+
40
+ ---
41
+
42
+ ## Installation
43
+
44
+ Install the package using `uv` (recommended) or standard `pip`:
45
+
46
+ ```bash
47
+ # Using uv (recommended)
48
+ uv tool install google-colab-cli
49
+
50
+ # Using pip
51
+ pip install google-colab-cli
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Quick Start
57
+
58
+ Run a CPU-based VM runtime, execute some code, and clean up:
59
+
60
+ ```bash
61
+ # 1. Provision a new session
62
+ colab new
63
+
64
+ # 2. Execute code from stdin
65
+ echo "print('Hello from Google Colab!')" | colab exec
66
+
67
+ # 3. Stop and release the VM resource
68
+ colab stop
69
+ ```
70
+
71
+ > [!NOTE]
72
+ > When only one session is active, you can omit the `-s, --session` option;
73
+ > the CLI automatically knows it.
74
+
75
+
76
+ ---
77
+
78
+ ## Command Index
79
+
80
+ Run `colab <command> --help` to view specific options, defaults, and detailed help.
81
+
82
+ ### Session Management
83
+ | Command | Description |
84
+ | --- | --- |
85
+ | `colab new [-s NAME] [--gpu GPU] [--tpu TPU]` | Allocate a new CPU, GPU, or TPU VM runtime |
86
+ | `colab sessions` | List all active sessions currently active on the backend |
87
+ | `colab status [-s NAME]` | Display hardware, status, and local metadata for active sessions |
88
+ | `colab restart-kernel [-s NAME]` | Restart the active session's Jupyter kernel |
89
+ | `colab stop [-s NAME]` | Terminate a session VM and tear down its keep-alive daemon |
90
+ | `colab url [-s NAME] [--open]` | Print or open a browser URL connecting to the active session |
91
+
92
+ ### Execution
93
+ | Command | Description |
94
+ | --- | --- |
95
+ | `colab run [--gpu GPU] [--tpu TPU] [--keep] SCRIPT [ARGS...]` | Run a local script on a fresh VM, forwarding arguments, then release it |
96
+ | `colab exec [-s NAME] [-f FILE] [--output-image PATH]` | Execute Python code from stdin, a local `.py` file, or a `.ipynb` notebook |
97
+ | `colab repl [-s NAME] [--output-image PATH]` | Start an interactive Python REPL on the VM (exits cleanly on piped EOF) |
98
+ | `colab console [-s NAME]` | Connect to a raw interactive TTY shell (tmux) on the remote VM |
99
+
100
+ ### File Operations
101
+ | Command | Description |
102
+ | --- | --- |
103
+ | `colab ls [-s NAME] [PATH]` | List remote files on the VM |
104
+ | `colab upload [-s NAME] LOCAL REMOTE` | Upload a local file to the VM filesystem |
105
+ | `colab download [-s NAME] REMOTE LOCAL` | Download a remote file from the VM filesystem |
106
+ | `colab rm [-s NAME] PATH` | Delete a remote file on the VM filesystem |
107
+ | `colab edit [-s NAME] PATH` | Edit a remote file in-place using your local `$EDITOR` |
108
+
109
+ ### Automation & Utilities
110
+ | Command | Description |
111
+ | --- | --- |
112
+ | `colab auth [-s NAME]` | Authenticate the VM for GCP services (BigQuery, GCS, etc.) |
113
+ | `colab drivemount [-s NAME] [PATH]` | Mount Google Drive on the VM (default: `/content/drive`) |
114
+ | `colab install [-s NAME] [-r FILE \| PKG...]` | Install packages on the VM using `uv` (falls back to `pip`) |
115
+ | `colab log [-s NAME] [-n N] [-o FILE]` | View or export session history (`.ipynb`, `.md`, `.txt`, `.jsonl`) |
116
+ | `colab pay` | Open the Colab subscription page to manage compute units |
117
+ | `colab version` | Print the installed version of the CLI |
118
+ | `colab update [--install]` | Check for a newer release (and optionally upgrade the CLI in place) |
119
+
120
+ ### Global Options
121
+ * `--auth {oauth2,adc}` — Authentication strategy for the Colab API (default: `adc`).
122
+ * `-c, --client-oauth-config PATH` — Path to public OAuth client credentials configuration (default: `~/.colab-cli-oauth-config.json`).
123
+ * `--config PATH` — Path to local session metadata storage (default: `~/.config/colab-cli/sessions.json`).
124
+ * `--logtostderr` — Direct debug logging output to stderr.
125
+
126
+ ---
127
+
128
+ ## Practical Examples
129
+
130
+ ### Accelerator Training with Checkpoint Retrieval
131
+
132
+ Provision an A100 GPU, install requirements, run a local training script, retrieve the resulting model weights, and terminate the VM:
133
+
134
+ ```bash
135
+ colab new -s trainer --gpu A100
136
+ colab install -s trainer torch transformers
137
+ colab exec -s trainer -f train.py
138
+ colab download -s trainer checkpoints/model.bin ./model.bin
139
+ colab stop -s trainer
140
+ ```
141
+
142
+ ### Workspace Notebook Execution with Drive Integration
143
+
144
+ Mount Google Drive, run a local notebook against the VM kernel (outputs are written back into `report_output.ipynb`), export a Markdown log of the execution, and clean up:
145
+
146
+ ```bash
147
+ colab new -s analysis
148
+ colab drivemount -s analysis
149
+ colab exec -s analysis -f report.ipynb
150
+ colab log -s analysis -o execution_log.md
151
+ colab stop -s analysis
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Usage Notes
157
+
158
+ * **TTY Requirements:** The interactive commands `repl` and `console` require a local TTY. When running inside automated scripts or pipelines, make sure to pipe stdin (e.g., `echo "print(1)" | colab repl`) to trigger non-interactive execution modes.
159
+ * **Transparent Code Execution:** When calling `colab exec -f file.py`, the CLI reads the file locally and transmits its content to the remote kernel. You do not need to manually upload files before execution.
160
+ * **Storage & State Paths:** Session tokens and metadata are stored at `~/.config/colab-cli/sessions.json`. Global CLI settings are located at `~/.config/colab-cli/settings.json`. These can be customized or isolated via the global `--config` flag.
161
+
162
+ ### Ephemeral Accelerator Jobs
163
+
164
+ Use `colab run` to run a local script on dedicated hardware without manual session lifecycle management. The CLI handles provisioning, script execution, and immediate VM teardown automatically:
165
+
166
+ ```bash
167
+ # Run train.py on a T4 GPU and release the VM on completion
168
+ colab run --gpu T4 train.py
169
+ ```
170
+
171
+ ### Shebang Execution Support
172
+
173
+ To execute a local file directly on a remote accelerator, place the `colab run` interpreter in the shebang line:
174
+
175
+ ```python
176
+ #!/usr/bin/env -S colab run --gpu L4 --keep
177
+ import torch
178
+
179
+ print("L4 GPU Available:", torch.cuda.is_available())
180
+ print("Device Name:", torch.cuda.get_device_name(0))
181
+ ```
182
+
183
+ Make the script executable (`chmod +x script.py`) and run it: `./script.py`. The `--keep` option tells the CLI to preserve the session VM on completion so you can re-execute or inspect logs.
184
+
185
+ ---
186
+
187
+ ## Deep Dive Documentation
188
+
189
+ For comprehensive architectural overviews and deep-dives into specific CLI sub-systems, refer to the detailed documentation:
190
+
191
+ * [Session Management & Keep-Alive Architecture](docs/01_session_management.md)
192
+ * [Interactive & Non-Interactive Execution Design](docs/02_execution_and_interactive.md)
193
+ * [File Management & Jupyter Contents API](docs/03_file_management.md)
194
+ * [Authentication Providers & VM Automation](docs/04_automation_and_utility.md)
195
+ * [Ephemeral Job Runner Design](docs/05_run_command.md)
196
+
197
+ To view interactive walkthroughs of eleven real-world automated scenarios, check out the [Demo Walkthroughs](docs/demos.md).
198
+
199
+ ---
200
+
201
+ ## Contributing
202
+
203
+ Feedback and contributions are welcome! Please read [`CONTRIBUTING.md`](./CONTRIBUTING.md) for details.
@@ -0,0 +1,181 @@
1
+ # Colab CLI
2
+
3
+ A command-line interface for Google Colab. Provision high-performance CPU, GPU, and TPU runtimes, execute local code, manage remote files, and orchestrate automated cloud pipelines — directly from your terminal.
4
+
5
+ Designed to support seamless developer productivity, headless automation, and AI agent integrations.
6
+
7
+ ---
8
+
9
+ ## Key Features
10
+
11
+ * **Instant VM Provisioning:** Spin up CPU, GPU (T4, L4, G4, H100, A100), or TPU (v5e1, v6e1) runtimes in seconds.
12
+ * **Robust Code Execution:** Run local Python scripts, Jupyter Notebooks (`.ipynb`), or piped `stdin` code; launch interactive REPLs or raw TTY console shells.
13
+ * **Ephemeral Job Runner (`colab run`):** Provision a fresh VM, execute a local script with forwarded arguments, retrieve output files, and automatically tear down the runtime in a single command.
14
+ * **Automatic Keep-Alive:** Built-in background daemon automatically prevents idle VM termination, keeping resource allocations active without requiring open browser tabs.
15
+ * **Seamless Workspace Automation:** Mount Google Drive, authenticate Google Cloud Platform (GCP) credentials, and install dependencies with high-performance `uv` package management.
16
+ * **State & Log Archival:** Inspect local session states or export interactive history logs to standard Jupyter Notebooks, Markdown, or structured JSONL.
17
+
18
+ ---
19
+
20
+ ## Installation
21
+
22
+ Install the package using `uv` (recommended) or standard `pip`:
23
+
24
+ ```bash
25
+ # Using uv (recommended)
26
+ uv tool install google-colab-cli
27
+
28
+ # Using pip
29
+ pip install google-colab-cli
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Quick Start
35
+
36
+ Run a CPU-based VM runtime, execute some code, and clean up:
37
+
38
+ ```bash
39
+ # 1. Provision a new session
40
+ colab new
41
+
42
+ # 2. Execute code from stdin
43
+ echo "print('Hello from Google Colab!')" | colab exec
44
+
45
+ # 3. Stop and release the VM resource
46
+ colab stop
47
+ ```
48
+
49
+ > [!NOTE]
50
+ > When only one session is active, you can omit the `-s, --session` option;
51
+ > the CLI automatically knows it.
52
+
53
+
54
+ ---
55
+
56
+ ## Command Index
57
+
58
+ Run `colab <command> --help` to view specific options, defaults, and detailed help.
59
+
60
+ ### Session Management
61
+ | Command | Description |
62
+ | --- | --- |
63
+ | `colab new [-s NAME] [--gpu GPU] [--tpu TPU]` | Allocate a new CPU, GPU, or TPU VM runtime |
64
+ | `colab sessions` | List all active sessions currently active on the backend |
65
+ | `colab status [-s NAME]` | Display hardware, status, and local metadata for active sessions |
66
+ | `colab restart-kernel [-s NAME]` | Restart the active session's Jupyter kernel |
67
+ | `colab stop [-s NAME]` | Terminate a session VM and tear down its keep-alive daemon |
68
+ | `colab url [-s NAME] [--open]` | Print or open a browser URL connecting to the active session |
69
+
70
+ ### Execution
71
+ | Command | Description |
72
+ | --- | --- |
73
+ | `colab run [--gpu GPU] [--tpu TPU] [--keep] SCRIPT [ARGS...]` | Run a local script on a fresh VM, forwarding arguments, then release it |
74
+ | `colab exec [-s NAME] [-f FILE] [--output-image PATH]` | Execute Python code from stdin, a local `.py` file, or a `.ipynb` notebook |
75
+ | `colab repl [-s NAME] [--output-image PATH]` | Start an interactive Python REPL on the VM (exits cleanly on piped EOF) |
76
+ | `colab console [-s NAME]` | Connect to a raw interactive TTY shell (tmux) on the remote VM |
77
+
78
+ ### File Operations
79
+ | Command | Description |
80
+ | --- | --- |
81
+ | `colab ls [-s NAME] [PATH]` | List remote files on the VM |
82
+ | `colab upload [-s NAME] LOCAL REMOTE` | Upload a local file to the VM filesystem |
83
+ | `colab download [-s NAME] REMOTE LOCAL` | Download a remote file from the VM filesystem |
84
+ | `colab rm [-s NAME] PATH` | Delete a remote file on the VM filesystem |
85
+ | `colab edit [-s NAME] PATH` | Edit a remote file in-place using your local `$EDITOR` |
86
+
87
+ ### Automation & Utilities
88
+ | Command | Description |
89
+ | --- | --- |
90
+ | `colab auth [-s NAME]` | Authenticate the VM for GCP services (BigQuery, GCS, etc.) |
91
+ | `colab drivemount [-s NAME] [PATH]` | Mount Google Drive on the VM (default: `/content/drive`) |
92
+ | `colab install [-s NAME] [-r FILE \| PKG...]` | Install packages on the VM using `uv` (falls back to `pip`) |
93
+ | `colab log [-s NAME] [-n N] [-o FILE]` | View or export session history (`.ipynb`, `.md`, `.txt`, `.jsonl`) |
94
+ | `colab pay` | Open the Colab subscription page to manage compute units |
95
+ | `colab version` | Print the installed version of the CLI |
96
+ | `colab update [--install]` | Check for a newer release (and optionally upgrade the CLI in place) |
97
+
98
+ ### Global Options
99
+ * `--auth {oauth2,adc}` — Authentication strategy for the Colab API (default: `adc`).
100
+ * `-c, --client-oauth-config PATH` — Path to public OAuth client credentials configuration (default: `~/.colab-cli-oauth-config.json`).
101
+ * `--config PATH` — Path to local session metadata storage (default: `~/.config/colab-cli/sessions.json`).
102
+ * `--logtostderr` — Direct debug logging output to stderr.
103
+
104
+ ---
105
+
106
+ ## Practical Examples
107
+
108
+ ### Accelerator Training with Checkpoint Retrieval
109
+
110
+ Provision an A100 GPU, install requirements, run a local training script, retrieve the resulting model weights, and terminate the VM:
111
+
112
+ ```bash
113
+ colab new -s trainer --gpu A100
114
+ colab install -s trainer torch transformers
115
+ colab exec -s trainer -f train.py
116
+ colab download -s trainer checkpoints/model.bin ./model.bin
117
+ colab stop -s trainer
118
+ ```
119
+
120
+ ### Workspace Notebook Execution with Drive Integration
121
+
122
+ Mount Google Drive, run a local notebook against the VM kernel (outputs are written back into `report_output.ipynb`), export a Markdown log of the execution, and clean up:
123
+
124
+ ```bash
125
+ colab new -s analysis
126
+ colab drivemount -s analysis
127
+ colab exec -s analysis -f report.ipynb
128
+ colab log -s analysis -o execution_log.md
129
+ colab stop -s analysis
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Usage Notes
135
+
136
+ * **TTY Requirements:** The interactive commands `repl` and `console` require a local TTY. When running inside automated scripts or pipelines, make sure to pipe stdin (e.g., `echo "print(1)" | colab repl`) to trigger non-interactive execution modes.
137
+ * **Transparent Code Execution:** When calling `colab exec -f file.py`, the CLI reads the file locally and transmits its content to the remote kernel. You do not need to manually upload files before execution.
138
+ * **Storage & State Paths:** Session tokens and metadata are stored at `~/.config/colab-cli/sessions.json`. Global CLI settings are located at `~/.config/colab-cli/settings.json`. These can be customized or isolated via the global `--config` flag.
139
+
140
+ ### Ephemeral Accelerator Jobs
141
+
142
+ Use `colab run` to run a local script on dedicated hardware without manual session lifecycle management. The CLI handles provisioning, script execution, and immediate VM teardown automatically:
143
+
144
+ ```bash
145
+ # Run train.py on a T4 GPU and release the VM on completion
146
+ colab run --gpu T4 train.py
147
+ ```
148
+
149
+ ### Shebang Execution Support
150
+
151
+ To execute a local file directly on a remote accelerator, place the `colab run` interpreter in the shebang line:
152
+
153
+ ```python
154
+ #!/usr/bin/env -S colab run --gpu L4 --keep
155
+ import torch
156
+
157
+ print("L4 GPU Available:", torch.cuda.is_available())
158
+ print("Device Name:", torch.cuda.get_device_name(0))
159
+ ```
160
+
161
+ Make the script executable (`chmod +x script.py`) and run it: `./script.py`. The `--keep` option tells the CLI to preserve the session VM on completion so you can re-execute or inspect logs.
162
+
163
+ ---
164
+
165
+ ## Deep Dive Documentation
166
+
167
+ For comprehensive architectural overviews and deep-dives into specific CLI sub-systems, refer to the detailed documentation:
168
+
169
+ * [Session Management & Keep-Alive Architecture](docs/01_session_management.md)
170
+ * [Interactive & Non-Interactive Execution Design](docs/02_execution_and_interactive.md)
171
+ * [File Management & Jupyter Contents API](docs/03_file_management.md)
172
+ * [Authentication Providers & VM Automation](docs/04_automation_and_utility.md)
173
+ * [Ephemeral Job Runner Design](docs/05_run_command.md)
174
+
175
+ To view interactive walkthroughs of eleven real-world automated scenarios, check out the [Demo Walkthroughs](docs/demos.md).
176
+
177
+ ---
178
+
179
+ ## Contributing
180
+
181
+ Feedback and contributions are welcome! Please read [`CONTRIBUTING.md`](./CONTRIBUTING.md) for details.
@@ -1,5 +1,10 @@
1
1
  ---
2
2
  log:
3
+ 2026-06-01: Enabled `colab update --install` self-update on macOS in addition to Linux. Refactored platform check logic to keep the implementation DRY and updated both tests and documentation. Also, on these platforms, an additional message is shown recommending `colab update --install` to upgrade in place, positioned above the standard `pip`/`uv` installation command.
4
+ 2026-05-27: Refactored `colab README` and `colab AGENT` to bundle `README.md` and `AGENTS.md` via Hatchling's `force-include` and read them using `importlib.resources` instead of `importlib.metadata`. `colab AGENT` now correctly prints `AGENTS.md`.
5
+ 2026-05-27: Extended `colab update --install` to detect if the CLI was installed via `uv tool install` (by checking if `sys.executable` contains `/uv/`) and if so, use `uv tool install -U google-colab-cli` to upgrade.
6
+ 2026-05-27: Updated auto-update upgrade hint to recommend `pip install --upgrade google-colab-cli` instead of `colab`, aligning with the PyPI package name.
7
+ 2026-05-27: `colab url` now emits BOTH the `?dbu=<urlencoded path>` query parameter (existing) AND a new `#datalabBackendUrl=<full URL>` hash fragment (new). Format: `https://<host>/notebooks/empty.ipynb?dbu=%2Ftun%2Fm%2F<endpoint>#datalabBackendUrl=<host>/tun/m/<endpoint>`. Why both: some Colab frontend code paths consult the hash fragment first and ignore `dbu` entirely, so the previously-emitted query-only form failed silently for those users (the frontend fell through to allocating a fresh VM via `/tun/m/assign`). The fragment value is a FULL URL with scheme + host (NOT just the path) and is emitted RAW (no URL encoding) because browsers don't decode the fragment before passing `location.hash` to page JS — Colab's parser calls `new URL(rawString)` directly. The fragment host always matches `--host` so Colab's same-origin enforcement on embedded backend URLs doesn't block the connection, and sandbox/dev users (`--host https://colab.sandbox.google.com`) get a sandbox fragment automatically. Three new test cases in `tests/test_url.py` cover the raw-encoding requirement (`%3A`/`%2F` must NOT appear in the fragment), the both-signals-present invariant, and `--open` propagating the fragment to `webbrowser.open()`. Integration-verified live against synthetic session state with three host shapes (default, sandbox, trailing-slash); all produced correctly-shaped URLs with no `//` artifacts.
3
8
  2026-05-07: Added a developer-only `colab whoami` subcommand (hidden from `colab --help`). Mints an access token via the same `auth.get_credentials(...)` path the rest of the CLI uses (honoring the global `--auth=...` flag), refreshes the credentials, then queries `https://oauth2.googleapis.com/tokeninfo` to print the email, scopes, audience, and expiry of whatever the CLI is about to send. Built specifically to short-circuit the "why is my call to colab.pa.googleapis.com 403-ing" debugging loop — the answer is almost always "missing scope" or "wrong identity", both of which `whoami` makes immediately visible. Hidden via `app.command(hidden=True)`; reachable via `colab whoami` or `colab whoami --help`. Suppressed from the daily-update banner check (added to `_AUTO_UPDATE_SUPPRESSED` in `cli.py`) so the banner doesn't obscure the auth output.
4
9
  2026-05-11: Removed the local-file update source (`update_file_path` setting and `_fetch_local` helper); `colab update` now consults PyPI only. Switched the default `update_url` to the canonical PyPI JSON API (`https://pypi.org/pypi/google-colab-cli/json`), which already exposes the `info.version` schema the auto-update subsystem expects. Re-added `colab update --install` as a public self-install path that runs `pip install -U google-colab-cli` against the current `sys.executable`; Linux-only (other platforms exit non-zero with an explanatory message), and a silent no-op when the cached `latest_version` is already at or below the current install.
5
10
  2026-05-12: Added an optional `timeout=` parameter to `ColabRuntime.execute_code` that flows through to both the `execute()` and `execute_interactive()` branches. `colab auth` and `colab drivemount` now pass `timeout=600` (10 min) via a shared `INTERACTIVE_AUTOMATION_TIMEOUT_SEC` constant in `commands/automation.py`. Background: `jupyter_kernel_client` defaults to a 10s wall-clock timeout that is consumed even when the kernel is idle waiting on `input_request`. With the drivefs hook intercepting that request and prompting the user to OAuth in their browser, any user that takes >10s to click through (essentially everyone) hit `TimeoutError` and saw "drivemount failed" even though the mount had actually succeeded server-side. The fix is scoped narrowly to the two human-in-the-loop subcommands; non-interactive paths (`colab exec`, `colab run`, `colab install`, `colab repl --pipe`, `colab console --pipe`) keep the upstream default since they receive continuous iopub traffic that resets the practical inactivity ceiling.
@@ -180,18 +185,23 @@ remediation guidance) rather than silently after ~1 minute via the daemon.
180
185
  across failed checks so transient network issues do not erase
181
186
  the cache.
182
187
  - **Notification**: If a new version is found, a non-intrusive message is
183
- printed to the console with a `Run 'pip install --upgrade colab' to
184
- update.` hint. The cached banner shown between fetches uses the generic
185
- `Run 'colab update' to update.` hint.
188
+ printed to the console with a `Run 'pip install --upgrade google-colab-cli' to
189
+ update.` hint. On Linux and macOS platforms where `--install` self-update is supported,
190
+ an additional hint `You can run 'colab update --install' to upgrade in place.`
191
+ is displayed above the pip/uv install command. The cached banner shown between
192
+ fetches uses the generic `Run 'colab update' to update.` hint.
186
193
  - **Self-install (`--install`)**: An opt-in `--install` flag (default
187
- `False`) makes `colab update` shell out to `pip install -U
188
- google-colab-cli` (using `sys.executable` so the upgrade lands in the
189
- same interpreter the CLI is running under). **Linux only**; on other
190
- platforms the command exits non-zero with an explanatory message. When
191
- the cached `latest_version` is already at or below the current install,
192
- the flag is a silent no-op so it is safe to wire into automation. If
193
- `pip` exits non-zero, `colab update --install` propagates the same
194
- exit code.
194
+ `False`) makes `colab update` upgrade the CLI in place (**Linux and macOS**).
195
+ It detects how the CLI was installed:
196
+ - If `sys.executable` contains `/uv/tools` (indicating it was installed via
197
+ `uv tool install`), it runs `uv tool install -U google-colab-cli`.
198
+ - Otherwise, runs `pip install -U google-colab-cli` using `sys.executable`
199
+ to ensure the upgrade lands in the same interpreter.
200
+ On other platforms, the command exits non-zero with an explanatory
201
+ message. When the cached `latest_version` is already at or below the
202
+ current install, the flag is a silent no-op so it is safe to wire into
203
+ automation. If the upgrade command exits non-zero, `colab update --install`
204
+ propagates the same exit code.
195
205
 
196
206
  ### 8. Identity Inspection (`colab whoami`) [developer-only]
197
207
 
@@ -235,6 +245,19 @@ remediation guidance) rather than silently after ~1 minute via the daemon.
235
245
  - openid
236
246
  ```
237
247
 
248
+ ### 9. README and AGENT (`colab README`, `colab AGENT`)
249
+
250
+ - **Action**: Print the bundled `README.md` or `AGENTS.md` file.
251
+ - **Implementation**:
252
+ - Uses `importlib.resources.files("colab_cli").joinpath(...)` to read the
253
+ bundled `README.md` (for `colab README`) or `AGENTS.md` (for `colab AGENT`)
254
+ from the package resources.
255
+ - The files are bundled into the package via Hatchling's `force-include`
256
+ configuration in `pyproject.toml`.
257
+ - If reading from resources fails (e.g. during development when not
258
+ installed), it falls back to reading the files from the project root.
259
+ - Prints the content to stdout.
260
+
238
261
  ## Implementation Details
239
262
 
240
263
  - **Code Injection**: Use a standard `run_code(session, code)` helper via
@@ -280,3 +303,10 @@ TDD is mandatory for all automation features.
280
303
  - **Test Case**: `creds.refresh()` is called before `creds.token` is read
281
304
  (regression against silently-`None` tokens for service-account /
282
305
  GCE-metadata creds).
306
+
307
+ ### 4. `README` and `AGENT` Commands
308
+
309
+ - **Test Case**: Verify `colab README` prints the expected content when package metadata is available.
310
+ - **Test Case**: Verify `colab AGENT` prints the same content.
311
+ - **Test Case**: Verify fallback to local `README.md` file when metadata is not available.
312
+ - **Test Case**: Verify error exit when both metadata and local file are unavailable.
@@ -14,9 +14,6 @@ dependencies = [
14
14
  "prompt-toolkit>=3.0.52",
15
15
  "pydantic>=2.12.5",
16
16
  "pygments>=2.19.2",
17
- "pytest>=9.0.2",
18
- "pytest-cov>=7.0.0",
19
- "pytest-mock>=3.15.1",
20
17
  "requests>=2.32.5",
21
18
  "rich>=14.3.3",
22
19
  "typer>=0.24.1",
@@ -37,6 +34,10 @@ source = "vcs"
37
34
  [tool.hatch.build.targets.wheel]
38
35
  packages = ["src/colab_cli"]
39
36
 
37
+ [tool.hatch.build.targets.wheel.force-include]
38
+ "README.md" = "colab_cli/README.md"
39
+ "COLAB_SKILL.md" = "colab_cli/COLAB_SKILL.md"
40
+
40
41
  [tool.uv]
41
42
  package = true
42
43
 
@@ -48,5 +49,8 @@ jupyter-kernel-client = { git = "https://github.com/googlecolab/jupyter-kernel-c
48
49
 
49
50
  [dependency-groups]
50
51
  dev = [
52
+ "pytest>=9.0.2",
53
+ "pytest-cov>=7.0.0",
54
+ "pytest-mock>=3.15.1",
51
55
  "ruff>=0.15.6",
52
56
  ]
@@ -23,6 +23,7 @@ callback (``cli.py``) calls ``check_for_updates`` once per day and
23
23
  """
24
24
 
25
25
  import json
26
+ import platform
26
27
  import subprocess
27
28
  import urllib.request
28
29
  from datetime import datetime, timezone
@@ -35,10 +36,18 @@ import typer
35
36
  from colab_cli.common import state
36
37
  from colab_cli.state import Settings
37
38
 
39
+ # PyPI distribution name (different from the importable package name `colab`).
40
+ PYPI_PACKAGE_NAME = "google-colab-cli"
41
+
38
42
 
39
43
  # ---------- Version detection -------------------------------------------
40
44
 
41
45
 
46
+ def is_self_install_supported() -> bool:
47
+ """Return True if self-install (--install) is supported on the current platform."""
48
+ return platform.system() in ("Linux", "Darwin")
49
+
50
+
42
51
  def get_app_version() -> str:
43
52
  """Return the installed package version, falling back to the git short hash."""
44
53
  try:
@@ -109,6 +118,8 @@ def announce_upgrade(
109
118
  typer.echo(
110
119
  f"\n[colab] A new version of Colab CLI is available: {latest} (current: {current})"
111
120
  )
121
+ if is_self_install_supported() and ("pip" in install_cmd or "uv" in install_cmd):
122
+ typer.echo("[colab] You can run 'colab update --install' to upgrade in place.")
112
123
  typer.echo(f"[colab] Run '{install_cmd}' to update.")
113
124
  if show_disable_hint:
114
125
  typer.echo(
@@ -122,6 +133,15 @@ def announce_upgrade(
122
133
  # ---------- Orchestration -----------------------------------------------
123
134
 
124
135
 
136
+ def _get_install_command() -> str:
137
+ """Return the recommended installation command based on the environment."""
138
+ import sys
139
+
140
+ if is_self_install_supported() and "/uv/tools/" in sys.executable:
141
+ return f"uv tool install -U {PYPI_PACKAGE_NAME}"
142
+ return f"pip install --upgrade {PYPI_PACKAGE_NAME}"
143
+
144
+
125
145
  def check_for_updates(quiet: bool = False) -> None:
126
146
  """Check PyPI for updates and print a message if a new version is available.
127
147
 
@@ -140,7 +160,7 @@ def check_for_updates(quiet: bool = False) -> None:
140
160
  announce_upgrade(
141
161
  pypi_v,
142
162
  current,
143
- "pip install --upgrade colab",
163
+ _get_install_command(),
144
164
  show_disable_hint=quiet,
145
165
  )
146
166
  elif not quiet:
@@ -211,15 +231,17 @@ def run_background_check() -> None:
211
231
  # ---------- Self-install ------------------------------------------------
212
232
 
213
233
 
214
- # PyPI distribution name (different from the importable package name `colab`).
215
- PYPI_PACKAGE_NAME = "google-colab-cli"
216
-
217
-
218
234
  def self_install() -> None:
219
- """Run ``pip install -U <PYPI_PACKAGE_NAME>`` to upgrade the CLI in place."""
235
+ """Upgrade the CLI in place, detecting uv vs pip."""
220
236
  import sys
221
237
 
222
- cmd = [sys.executable, "-m", "pip", "install", "-U", PYPI_PACKAGE_NAME]
238
+ # If the executable path contains "/uv/", we assume it was installed via
239
+ # `uv tool install` and use `uv` to upgrade it.
240
+ if "/uv/tools/" in sys.executable:
241
+ cmd = ["uv", "tool", "install", "-U", PYPI_PACKAGE_NAME]
242
+ else:
243
+ cmd = [sys.executable, "-m", "pip", "install", "-U", PYPI_PACKAGE_NAME]
244
+
223
245
  typer.echo(f"[colab] Running: {' '.join(cmd)}")
224
246
  result = subprocess.run(cmd)
225
247
  if result.returncode != 0:
@@ -105,6 +105,10 @@ def callback(
105
105
  "help",
106
106
  "url",
107
107
  "whoami",
108
+ "readme",
109
+ "README",
110
+ "skill",
111
+ "SKILL",
108
112
  }
109
113
  if ctx.invoked_subcommand not in _AUTO_UPDATE_SUPPRESSED:
110
114
  auto_update.run_background_check()
@@ -234,7 +234,7 @@ def run_command(
234
234
  ),
235
235
  ] = False,
236
236
  ):
237
- """Run a Python script on a fresh Colab VM, then release the VM.
237
+ """Run a Python script on a fresh Colab VM, then release the VM
238
238
 
239
239
  Designed to be used as a shebang interpreter, e.g.
240
240
 
@@ -27,7 +27,6 @@ from colab_cli.client import (
27
27
  PostAssignmentResponse,
28
28
  Variant,
29
29
  )
30
- from colab_cli.commands.automation import INTERACTIVE_AUTOMATION_TIMEOUT_SEC
31
30
  from colab_cli.utils import get_status_code
32
31
  from colab_cli.state import SessionState
33
32
  from colab_cli.runtime import ColabRuntime
@@ -247,11 +246,12 @@ def new(
247
246
  typer.echo("[colab] Session READY.")
248
247
 
249
248
 
250
- def restart(
249
+ def restart_kernel(
251
250
  session: Annotated[
252
251
  Optional[str], typer.Option("-s", "--session", help="Session name")
253
252
  ] = None,
254
253
  ):
254
+ """Restart a session's kernel"""
255
255
  from colab_cli.common import state
256
256
 
257
257
  name = state.resolve_session(session)
@@ -274,7 +274,10 @@ def restart(
274
274
  on_session_started=on_sess_started,
275
275
  )
276
276
 
277
- runtime.restart(timeout=INTERACTIVE_AUTOMATION_TIMEOUT_SEC)
277
+ try:
278
+ runtime.restart()
279
+ finally:
280
+ runtime.stop()
278
281
 
279
282
 
280
283
  def sessions_command():
@@ -502,7 +505,7 @@ def keep_alive(
502
505
  def register(app: typer.Typer):
503
506
  app.command()(new)
504
507
  app.command(name="sessions")(sessions_command)
505
- app.command()(restart)
508
+ app.command(name="restart-kernel")(restart_kernel)
506
509
  app.command()(status)
507
510
  app.command()(stop)
508
511
  app.command(hidden=True)(keep_alive)