urun-cli 0.1.2__tar.gz → 0.3.0__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.
- {urun_cli-0.1.2 → urun_cli-0.3.0}/.gitignore +4 -0
- urun_cli-0.3.0/CHANGELOG.md +24 -0
- {urun_cli-0.1.2 → urun_cli-0.3.0}/PKG-INFO +49 -23
- urun_cli-0.3.0/README.md +132 -0
- {urun_cli-0.1.2 → urun_cli-0.3.0}/pyproject.toml +1 -1
- {urun_cli-0.1.2 → urun_cli-0.3.0}/src/urun/api.py +12 -0
- urun_cli-0.3.0/src/urun/cli.py +377 -0
- urun_cli-0.3.0/src/urun/config.py +58 -0
- urun_cli-0.3.0/src/urun/deps.py +13 -0
- urun_cli-0.3.0/src/urun/discovery.py +170 -0
- urun_cli-0.1.2/CHANGELOG.md +0 -18
- urun_cli-0.1.2/README.md +0 -106
- urun_cli-0.1.2/src/urun/cli.py +0 -126
- urun_cli-0.1.2/src/urun/deps.py +0 -80
- urun_cli-0.1.2/src/urun/discovery.py +0 -144
- {urun_cli-0.1.2 → urun_cli-0.3.0}/LICENSE +0 -0
- {urun_cli-0.1.2 → urun_cli-0.3.0}/SECURITY.md +0 -0
- {urun_cli-0.1.2 → urun_cli-0.3.0}/src/urun/__init__.py +0 -0
- {urun_cli-0.1.2 → urun_cli-0.3.0}/src/urun/errors.py +0 -0
- {urun_cli-0.1.2 → urun_cli-0.3.0}/src/urun/manifest.py +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
- Implement the `urun org` / `urun org id` command: print the caller's org id
|
|
6
|
+
(resolved via the control-plane org-config endpoint).
|
|
7
|
+
- Implement `urun auth jwks set`: register the org's trusted JWKS for federated
|
|
8
|
+
identity, via `--jwks-url` or `--jwks-json` (file or stdin), with optional
|
|
9
|
+
`--issuer`/`--audience`. This registers a trust relationship only; JWTs are
|
|
10
|
+
issued out of band and the CLI never mints, fetches, or stores one.
|
|
11
|
+
- Add `ApiClient.register_trusted_jwks`, calling `POST /org-config/trusted-jwks`.
|
|
12
|
+
|
|
13
|
+
## 0.2.0
|
|
14
|
+
|
|
15
|
+
- Bumped past 0.1.1/0.1.2 because both filenames were occupied by previously-deleted PyPI artifacts.
|
|
16
|
+
- Drop the org-id requirement from `urun deploy`; authentication now relies solely on the API key.
|
|
17
|
+
- Add `urun login`, `urun run`, and `urun org`/`urun auth` subcommands.
|
|
18
|
+
|
|
19
|
+
## 0.1.0
|
|
20
|
+
|
|
21
|
+
- Initial public `urun deploy` CLI.
|
|
22
|
+
- Deploy from a Python app file with local Python imports included automatically.
|
|
23
|
+
- Source manifest generation, dependency declaration upload, and API deploy flow.
|
|
24
|
+
- Public docs for the config-free v1 CLI surface.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: urun-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: End-user CLI for deploying apps to urun
|
|
5
5
|
Project-URL: Homepage, https://urun.sh
|
|
6
6
|
Project-URL: Repository, https://github.com/urun-sh/urun-cli
|
|
@@ -51,34 +51,47 @@ uvx urun-cli --version
|
|
|
51
51
|
|
|
52
52
|
## Quick start
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
Today, an operator manually vends an org-scoped deploy API key. Save it locally
|
|
55
|
+
with `urun login`:
|
|
55
56
|
|
|
56
57
|
```bash
|
|
57
|
-
|
|
58
|
+
urun login --api-key urun_<32hex>
|
|
58
59
|
```
|
|
59
60
|
|
|
60
|
-
|
|
61
|
+
`urun login` verifies the key with the urun API and stores credentials for later
|
|
62
|
+
commands. The future browser-based login flow is not available in this CLI
|
|
63
|
+
release.
|
|
64
|
+
|
|
65
|
+
For CI or one-off commands, you can still use the environment variable:
|
|
61
66
|
|
|
62
67
|
```bash
|
|
63
|
-
|
|
64
|
-
print("hello from urun")
|
|
65
|
-
PY
|
|
68
|
+
export URUN_API_KEY=urun_<32hex>
|
|
66
69
|
```
|
|
67
70
|
|
|
68
|
-
|
|
71
|
+
Create `app.py`:
|
|
69
72
|
|
|
70
|
-
```
|
|
71
|
-
urun
|
|
73
|
+
```python
|
|
74
|
+
import urun
|
|
75
|
+
from urun import App
|
|
76
|
+
|
|
77
|
+
app = App("hello-h100")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@app.function(gpus="h100:1")
|
|
81
|
+
def hello(ctx: urun.Context):
|
|
82
|
+
print(f"running on {ctx.device}")
|
|
83
|
+
return {"device": str(ctx.device)}
|
|
72
84
|
```
|
|
73
85
|
|
|
74
|
-
|
|
86
|
+
Run it:
|
|
75
87
|
|
|
76
88
|
```bash
|
|
77
|
-
urun
|
|
89
|
+
urun run app.py
|
|
78
90
|
```
|
|
79
91
|
|
|
80
|
-
|
|
81
|
-
|
|
92
|
+
In this release, `urun run` uses the same deploy pipeline as `urun deploy`.
|
|
93
|
+
`deploy` remains available as the lower-level command while the full
|
|
94
|
+
deploy/run/monitor workflow is being built.
|
|
82
95
|
|
|
83
96
|
## What gets deployed
|
|
84
97
|
|
|
@@ -86,11 +99,11 @@ ID, login step, or local project setup for the v1 CLI.
|
|
|
86
99
|
|
|
87
100
|
| Entrypoint | Included source |
|
|
88
101
|
| --- | --- |
|
|
89
|
-
| `urun deploy app.py` | `app.py`
|
|
90
|
-
| `urun deploy -m my_package.main` | Python files in the containing package |
|
|
102
|
+
| `urun deploy app.py` | `app.py` and local Python files it imports |
|
|
91
103
|
|
|
92
|
-
|
|
93
|
-
`requirements.txt`
|
|
104
|
+
Dependencies are declared in your urun app code. Project-level files such as
|
|
105
|
+
`pyproject.toml` and `requirements.txt` are not uploaded as dependency
|
|
106
|
+
declarations by the CLI.
|
|
94
107
|
|
|
95
108
|
Generated/cache content such as `.git`, dotfiles, `__pycache__`, and `.pyc`
|
|
96
109
|
files is excluded. Add `.urunignore` to exclude additional paths.
|
|
@@ -100,12 +113,13 @@ auto-included yet.
|
|
|
100
113
|
|
|
101
114
|
## Common options
|
|
102
115
|
|
|
116
|
+
Shared by `run` and `deploy`:
|
|
117
|
+
|
|
103
118
|
| Option | Description |
|
|
104
119
|
| --- | --- |
|
|
105
|
-
| `-m, --module` | Deploy a Python module entrypoint, e.g. `my_package.main`. |
|
|
106
120
|
| `--name` | Override the derived app name. |
|
|
107
|
-
| `--api-url` | Override the API URL; defaults to `https://api.urun.sh/v1`. |
|
|
108
|
-
| `--api-key` | API key;
|
|
121
|
+
| `--api-url` | Override the API URL; defaults to `URUN_API_URL`, saved login credentials, or `https://api.urun.sh/v1`. |
|
|
122
|
+
| `--api-key` | Deploy API key; defaults to `URUN_API_KEY` or saved login credentials. |
|
|
109
123
|
| `--no-wait` | Finalize but do not poll for readiness. |
|
|
110
124
|
| `--poll-interval`, `--timeout` | Control readiness polling. |
|
|
111
125
|
|
|
@@ -113,11 +127,11 @@ auto-included yet.
|
|
|
113
127
|
|
|
114
128
|
| Error | Fix |
|
|
115
129
|
| --- | --- |
|
|
116
|
-
| `missing API key` |
|
|
130
|
+
| `missing API key` | Run `urun login`, set `URUN_API_KEY`, or pass `--api-key`. |
|
|
117
131
|
| `invalid API key format` | Use `urun_<32 lowercase hex chars>`. |
|
|
118
132
|
| `entrypoint not found` | Run from the project root or pass the entrypoint path. |
|
|
119
133
|
| `path is outside the project root` | Move the file under the project before deploying. |
|
|
120
|
-
| Expected files are missing |
|
|
134
|
+
| Expected files are missing | Import local Python files from `app.py`; non-Python assets are not auto-included yet. |
|
|
121
135
|
|
|
122
136
|
## Development
|
|
123
137
|
|
|
@@ -126,3 +140,15 @@ Contributing and test instructions are in [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
|
126
140
|
## License
|
|
127
141
|
|
|
128
142
|
MIT.
|
|
143
|
+
|
|
144
|
+
## Development environment
|
|
145
|
+
|
|
146
|
+
This repo has a Nix/direnv/devcontainer baseline:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
direnv allow
|
|
150
|
+
just sync
|
|
151
|
+
just check
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Use VS Code Dev Containers to open the repository with the same toolchain in a container. Copy `devcontainer.env.example` to `.devcontainer.env` if you need to pass local git identity or other non-secret development settings into the container.
|
urun_cli-0.3.0/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# urun CLI
|
|
2
|
+
|
|
3
|
+
Deploy Python apps to urun from your terminal.
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/urun-cli/)
|
|
6
|
+
[](https://pypi.org/project/urun-cli/)
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
uv tool install urun-cli
|
|
12
|
+
# or
|
|
13
|
+
pip install urun-cli
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The package installs the `urun` command:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
urun --version
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
For one-off `uvx` usage:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
uvx --from urun-cli urun --version
|
|
26
|
+
# or the package-matching command alias
|
|
27
|
+
uvx urun-cli --version
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick start
|
|
31
|
+
|
|
32
|
+
Today, an operator manually vends an org-scoped deploy API key. Save it locally
|
|
33
|
+
with `urun login`:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
urun login --api-key urun_<32hex>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`urun login` verifies the key with the urun API and stores credentials for later
|
|
40
|
+
commands. The future browser-based login flow is not available in this CLI
|
|
41
|
+
release.
|
|
42
|
+
|
|
43
|
+
For CI or one-off commands, you can still use the environment variable:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
export URUN_API_KEY=urun_<32hex>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Create `app.py`:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
import urun
|
|
53
|
+
from urun import App
|
|
54
|
+
|
|
55
|
+
app = App("hello-h100")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@app.function(gpus="h100:1")
|
|
59
|
+
def hello(ctx: urun.Context):
|
|
60
|
+
print(f"running on {ctx.device}")
|
|
61
|
+
return {"device": str(ctx.device)}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Run it:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
urun run app.py
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
In this release, `urun run` uses the same deploy pipeline as `urun deploy`.
|
|
71
|
+
`deploy` remains available as the lower-level command while the full
|
|
72
|
+
deploy/run/monitor workflow is being built.
|
|
73
|
+
|
|
74
|
+
## What gets deployed
|
|
75
|
+
|
|
76
|
+
`urun deploy` creates a source manifest from your Python entrypoint:
|
|
77
|
+
|
|
78
|
+
| Entrypoint | Included source |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `urun deploy app.py` | `app.py` and local Python files it imports |
|
|
81
|
+
|
|
82
|
+
Dependencies are declared in your urun app code. Project-level files such as
|
|
83
|
+
`pyproject.toml` and `requirements.txt` are not uploaded as dependency
|
|
84
|
+
declarations by the CLI.
|
|
85
|
+
|
|
86
|
+
Generated/cache content such as `.git`, dotfiles, `__pycache__`, and `.pyc`
|
|
87
|
+
files is excluded. Add `.urunignore` to exclude additional paths.
|
|
88
|
+
|
|
89
|
+
Non-Python assets such as templates, static files, and data files are not
|
|
90
|
+
auto-included yet.
|
|
91
|
+
|
|
92
|
+
## Common options
|
|
93
|
+
|
|
94
|
+
Shared by `run` and `deploy`:
|
|
95
|
+
|
|
96
|
+
| Option | Description |
|
|
97
|
+
| --- | --- |
|
|
98
|
+
| `--name` | Override the derived app name. |
|
|
99
|
+
| `--api-url` | Override the API URL; defaults to `URUN_API_URL`, saved login credentials, or `https://api.urun.sh/v1`. |
|
|
100
|
+
| `--api-key` | Deploy API key; defaults to `URUN_API_KEY` or saved login credentials. |
|
|
101
|
+
| `--no-wait` | Finalize but do not poll for readiness. |
|
|
102
|
+
| `--poll-interval`, `--timeout` | Control readiness polling. |
|
|
103
|
+
|
|
104
|
+
## Troubleshooting
|
|
105
|
+
|
|
106
|
+
| Error | Fix |
|
|
107
|
+
| --- | --- |
|
|
108
|
+
| `missing API key` | Run `urun login`, set `URUN_API_KEY`, or pass `--api-key`. |
|
|
109
|
+
| `invalid API key format` | Use `urun_<32 lowercase hex chars>`. |
|
|
110
|
+
| `entrypoint not found` | Run from the project root or pass the entrypoint path. |
|
|
111
|
+
| `path is outside the project root` | Move the file under the project before deploying. |
|
|
112
|
+
| Expected files are missing | Import local Python files from `app.py`; non-Python assets are not auto-included yet. |
|
|
113
|
+
|
|
114
|
+
## Development
|
|
115
|
+
|
|
116
|
+
Contributing and test instructions are in [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
117
|
+
|
|
118
|
+
## License
|
|
119
|
+
|
|
120
|
+
MIT.
|
|
121
|
+
|
|
122
|
+
## Development environment
|
|
123
|
+
|
|
124
|
+
This repo has a Nix/direnv/devcontainer baseline:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
direnv allow
|
|
128
|
+
just sync
|
|
129
|
+
just check
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Use VS Code Dev Containers to open the repository with the same toolchain in a container. Copy `devcontainer.env.example` to `.devcontainer.env` if you need to pass local git identity or other non-secret development settings into the container.
|
|
@@ -32,6 +32,18 @@ class ApiClient:
|
|
|
32
32
|
def deployment_status(self, manifest_hash: str) -> dict[str, Any]:
|
|
33
33
|
return self._json("GET", f"/deployment-status/{manifest_hash}", None)
|
|
34
34
|
|
|
35
|
+
def org_config(self) -> dict[str, Any]:
|
|
36
|
+
return self._json("GET", "/org-config", None)
|
|
37
|
+
|
|
38
|
+
def register_trusted_jwks(self, payload: dict[str, Any]) -> dict[str, Any]:
|
|
39
|
+
"""Register this org's trusted JWKS with the control plane.
|
|
40
|
+
|
|
41
|
+
The org is derived server-side from the API key; the payload carries only
|
|
42
|
+
the trusted key source (jwks_url OR jwks_json) plus optional iss/aud. This
|
|
43
|
+
records a trust relationship — it does not mint or fetch a JWT.
|
|
44
|
+
"""
|
|
45
|
+
return self._json("POST", "/org-config/trusted-jwks", payload)
|
|
46
|
+
|
|
35
47
|
def _json(self, method: str, path: str, body: dict[str, Any] | None) -> dict[str, Any]:
|
|
36
48
|
data = (
|
|
37
49
|
None
|